Search code examples
iphoneiosnsstringuitouchcore-text

how to get tap events in a text using core text framework in iOS


i am doing a reader application in IPAD ,the book data is stored in Sqlite DB,i render this content of DB in a view through core text...the formate of my text is like this e.g.:1 haii this is iPhone. 2 this is iPad. 3 this is mac. etc etc..i just want to get touch events while touching the text.for example if i tap the first sentence,,the fist sentence only must be selected with any color,and trigger a popup(subview or alert view or action sheet)like the image belowenter image description here

i am having this code to make the text to shown in a view

NSMutableString *combined = [NSMutableString string];

    for(NSUInteger idx = 0; idx < [delegatee.allSelectedVerseEnglish count]; idx++) {
        [combined appendFormat:@"  %d %@", 
         idx + 1, 
         [delegatee.allSelectedVerseEnglish objectAtIndex:idx]];

    }

    self.multiPageView.text =combined;

combined is the string contains verses oif the bible of the selected chapter,so when i click the first verse it need to be selected like the image below and pops up a subview or alert view like the image below,and by selection that verse must be stored in somewhere or copy to clipboard.multiPageView is the view that render the core text .i want just like in olive tree bible application or ibook.

i am not using the web view,due to some limitation in the web view..is there any idea how to do this..,please help me. Thanks in advance. EDIT:

- (void)textViewDidEndEditing:(UITextView *)textView
{

    mainpopupview.frame =CGRectMake(0, 0, 768, 1004)    ;
    [self.view addSubview:mainpopupview];

    NSRange selectedRange = [textView selectedRange];
    NSString *backString = [maintextview.text substringToIndex:selectedRange.location];
    NSRange backRange = [backString rangeOfString:@"." options:NSBackwardsSearch];
    NSRange backRangee = [backString rangeOfString:@"." options:NSBackwardsSearch];
    int  myRangeLenght = backRangee.location - backRange.location;
    NSRange myStringRange = NSMakeRange (backRange.location, myRangeLenght);
    NSString *forwardString  = [maintextview.text substringFromIndex:backRange.location];
    NSLog(@"%@",[[forwardString componentsSeparatedByString:@"."] objectAtIndex:1]);
    NSLog (@"%@",  [maintextview.text substringWithRange:myStringRange]);

    NSString * myStringTxt = [[forwardString componentsSeparatedByString:@"."] objectAtIndex:1];
    NSLog(@"1 %@", myStringTxt);

      //  maintextview.textColor = [UIColor yellowColor];

    NSRange myStringRangee = [maintextview.text rangeOfString:myStringTxt];
    [maintextview select:self];
    maintextview.selectedRange = myStringRangee;
    }

myStringTxt contains the correct verse(menz text between .to .but i want to elect this text.


Solution

  • I think you can wire up UITextview's UIControlEventEditingChanged to some method. So when ever the user selects something that method would be called. Inside the method you can obtain the selected text using,

    NSRange range = [txtView selectedRange];
    NSString *str = [txtView.text substringWithRange:range];
    

    From the selected string you can perform the actions you like.

    If your text view is editable you can get,

    NSLog(@"%d",range.location);
    

    Once you know the location you can create a range and select string. This and this has relevant info.

    //Here is the complete sample code.

      {
            sampleTextView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 60, 300)];
            sampleTextView.text = @"This is sample text to find text under touch. I am not going to use any private api.How am i supposed to do?.Let me see.";
            sampleTextView.editable = YES;
            sampleTextView.delegate = (id)self;
            [self.view addSubview:sampleTextView];
        }
    - (void)textViewDidBeginEditing:(UITextView *)textView
    {
    
        [NSTimer scheduledTimerWithTimeInterval:0.001 target:sampleTextView   selector:@selector(resignFirstResponder) userInfo:nil repeats:NO];
    }
    
    - (void)textViewDidEndEditing:(UITextView *)textView
    {
        NSRange selectedRange = [textView selectedRange];
        NSString *backString = [sampleTextView.text substringToIndex:selectedRange.location];
        NSRange backRange = [backString rangeOfString:@" " options:NSBackwardsSearch];
        NSString *forwardString  = [sampleTextView.text substringFromIndex:backRange.location];
        NSLog(@"%@",[[forwardString componentsSeparatedByString:@" "] objectAtIndex:1]);
    }
    

    EDIT :

    I have updated the code based on your requirement. Please find it below,

    UITextView *textview;
    BOOL toggle;
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        textview = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
        textview.delegate = (id)self;
        textview.inputView = [[UIView alloc] init];
        textview.text = @"Let's hope the text selection works programmatically!";
        [self.view addSubview:textview];
    }
    
    - (void)textViewDidChangeSelection:(UITextView *)textView
    {    
        NSRange selectedRange = [textView selectedRange];
        NSString *backString = [textView.text substringToIndex:selectedRange.location];
        NSRange backRange = [backString rangeOfString:@" " options:NSBackwardsSearch];
        NSString *forwardString  = [textView.text substringFromIndex:backRange.location];
    
        NSLog(@"%@",[[forwardString componentsSeparatedByString:@" "] objectAtIndex:1]);
    
        NSRange ran = [textView.text rangeOfString:[[forwardString componentsSeparatedByString:@" "] objectAtIndex:1]];
    
        if (!toggle)
        {
            [self performSelector:@selector(selectText:) withObject:[NSValue valueWithRange:ran] afterDelay:0.001];
        }
        else
        {
            toggle = !toggle;
        }
    }
    
    -(void)selectText:(NSValue *)sender
    {
        toggle = !toggle;
    
        textview.selectedRange = [sender rangeValue];
    }