Reputation: 3
-Goal: Get the Origin of a particular section of Text in a UITextView
Below is a link to a Screenshot of an app I am working on. Please view it as it is easier to explain with it. Image Link: ScreenShot
This is a start to a Fill in the Blanks style game. I am currently trying to get the x,y coordinates of each of the underscores. When a word on the bottom of the screen is tapped it will move to the next available underscore space.
Currently I have written this code to do what I need, but it is very ugly, barely works AND is not very flexible. See Below:
// self.mainTextView is where the text with the underscores is coming from
NSString *text = self.mainTextView.text;
NSString *substring = [text substringToIndex:[text rangeOfString:@"__________"].location];
CGSize size = [substring sizeWithFont:self.mainTextView.font];
CGPoint p = CGPointMake((int)size.width % (int)self.mainTextView.frame.size.width, ((int)size.width / (int)self.mainTextView.frame.size.width) * size.height);
// What is going on here is for some reason everytime there is a new
// line my x coordinate is offset by what seems to be 10 pixels...
// So was my ugly fix for it..
// The UITextView width is 280
CGRect mainTextFrame = [self.mainTextView frame];
p.x = p.x + mainTextFrame.origin.x + 9;
if ((int)size.width > 280) {
NSLog(@"width: 280");
p.x = p.x + mainTextFrame.origin.x + 10;
}
if ((int)size.width > 560) {
NSLog(@"width: 560");
p.x = p.x + mainTextFrame.origin.x + 12;
}
if ((int)size.width > 840) {
p.x = p.x + mainTextFrame.origin.x + 14;
}
p.y = p.y + mainTextFrame.origin.y + 5;
// Sender is the button that was pressed
newFrame = [sender frame];
newFrame.origin = p;
[UIView animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionAllowAnimatedContent|UIViewAnimationCurveEaseInOut
animations:^{
[sender setFrame:newFrame];
}
completion:^(BOOL finished){
}
];
So the the best question for me to ask is What is a better way of going about this? And or do you have any suggestions? How would you go about this?
Thank you for your time in advance.
Upvotes: 0
Views: 996
Reputation: 2919
Rather than manually searching each occurrence of the underscore. make use of NSRegularExpression
Which makes your task so simple and easy. After the matched Strings are found then make use of the NSTextCheckingResult
to get the location of each matched strings.
More Explaination:
You can make use of the regular expression inorder get all the occurence of the underscore.This is obtanied using the following code.
NSError *error = NULL;
NSString *pattern = @"_*_"; // pattern to search underscore.
NSString *string = self.textView.text;
NSRange range = NSMakeRange(0, string.length);
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regex matchesInString:string options:NSMatchingProgress range:range];
Once you get all the Matching Patterns you can get the location of the matched strings using the following code.
[matches enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[NSTextCheckingResult class]])
{
NSTextCheckingResult *match = (NSTextCheckingResult *)obj;
CGRect rect = [self frameOfTextRange:match.range inTextView:self.textView];
//get location of all the matched strings.
}
}];
Hope this answers all your concerns!
Upvotes: 1