Alex Rivera | Logout

Pixel-Position of Cursor in UITextView

Asked 2010-04-13T21:32:19.000
26

Is there a way of getting the position (CGPoint) of the cursor (blinking bar) in an UITextView (preferable relative to its content). I don’t mean the location as an NSRange. I need something around:

- (CGPoint)cursorPosition;

It should be a non-private API way.

Edit
Report

2 Answers

1

I try to mark a selected text, i.e. I receive a NSRange and want to draw a yellow rectangle behind that text. Is there another way?

I can advise you some trick:

NSRange selectedRange = myTextView.selectedRange;
[myTextView select:self];
UIMenuController* sharedMenu = [UIMenuController sharedMenuController];
CGRect menuFrame = [sharedMenu menuFrame];
[sharedMenu setMenuVisible:NO];
myTextView.selectedRange = selectedRange

Using this code, you can know get the position of the cut/copy/past menu and there place your yellow rectangle.

I did not find a way to get the menu position witout forcing it to appear by a simulated select operation.

Regards Assayag

answered 2010-08-18T14:06:27.123
1

Take a screenshot of the UITextView, then search the pixel data for colors that match the color of the cursor.

-(CGPoint)positionOfCursorForTextView:(UITextView)textView {
     //get CGImage from textView
     UIGraphicsBeginImageContext(textView.bounds.size);
     [textView.layer renderInContext:UIGraphicsGetCurrentContext()];
     CGImageRef textImageRef = UIGraphicsGetImageFromCurrentImageContext().CGImage;
     UIGraphicsEndImageContext();  

     //get raw pixel data
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
     uint8_t * textBuffer = (uint8_t*)malloc(Width * Height * 4);
     NSUInteger bytesPerRow = 4 * Width;
     NSUInteger bitsPerComponent = 8;
     CGContextRef context = CGBitmapContextCreate(textBuffer, Width, Height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);


     CGColorSpaceRelease(colorSpace);

     CGContextDrawImage(context, CGRectMake(0, 0, Width, Height), textImageRef);
     CGContextRelease(context);

     //search 

     for(int y = 0; y < Height; y++)
     {
         for(int x = 0; x < Width * 4; x += 4)
         {
             int red   = textBuffer[y * 4 * (NSInteger)Width + x];
             int green = textBuffer[y * 4 * (NSInteger)Width + x + 1];    
             int blue  = textBuffer[y * 4 * (NSInteger)Width + x + 2];  
             int alpha   = textBuffer[y * 4 * (NSInteger)Width + x + 3];    


             if(COLOR IS CLOSE TO COLOR OF CURSOR)
             {
                 free(textBuffer);
                 CGImageRelease(textImageRef);
                 return CGPointMake(x/4, y);
             }
         }
     }

     free(textBuffer);
     CGImageRelease(textImageRef);
     return CGPointZero;
}
answered 2011-03-06T00:08:41.613

Your Answer