Reputation: 1966
Edited
I have a textview with a UITapGestureRecognizer to identify words on which people tap. The UITextVIew itself, however, changes in size based on the quantity of text loaded in the textView. Right now the textView is not recognizing any taps that occur on text in textview beyond the initial size of the screen.
The tap recognizer is currently initialized in viewDidLoad as I only want to create it once. It is therefore created before the view is laid out. Should I move it to viewwillappear or some other method that fires after the size of the textview is known? Or is there a way to let the tapRecognizer know the textview is now larger?
The screen uses autplayout so this may be part of the problem.
//This is how the recognizer is created in viewdidload:
UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc]initWithTarget:self
action:@selector(handleTap:)];
tapList.cancelsTouchesInView = NO;
[self.myView addGestureRecognizer:tapRec];
//This is method that handles tap
- (void) handleTap:(UITapGestureRecognizer *)recognizer{
UITextView *textView = (UITextView *)recognizer.view;
CGPoint location = [recognizer locationInView:textView];
CGPoint position = CGPointMake(location.x, location.y);
UITextPosition *tapPosition = [textView closestPositionToPoint:position];
UITextRange *textRange = [textView.tokenizer rangeEnclosingPosition:tapPosition withGranularity:UITextGranularityLine inDirection:UITextLayoutDirectionRight];
NSString *tappedLine = [textView textInRange:textRange];
}
//This is where size of view is changed in response to quantity of text in viewwillappear
CGFloat fixedWidth = myView.frame.size.width;
//MAXFLOAT IS THE maximum float system allows
CGSize newSize = [myView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = myView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
myView.frame = newFrame;
[self.myView sizeToFit];
self.myView.editable = NO;
self.myView.scrollEnabled=NO;
Thanks for any suggestions.
Upvotes: 0
Views: 211
Reputation: 123
I made small test just with your code. For me all works fine. I added timer with change text every 7 seconds for test. After change size I can always tap to any text in the textView with new size. Maybe problem in some additional code ?
My test project xCode 9.2: https://ufile.io/ngo47
#import "ViewController.h"
@interface ViewController ()
{
IBOutlet UITextView* myView;
NSTimer* timer;
}
@end
@implementation ViewController
//This is method that handles tap
- (void) handleTap:(UITapGestureRecognizer *)recognizer{
UITextView *textView = (UITextView *)recognizer.view;
CGPoint location = [recognizer locationInView:textView];
CGPoint position = CGPointMake(location.x, location.y);
UITextPosition *tapPosition = [textView closestPositionToPoint:position];
UITextRange *textRange = [textView.tokenizer rangeEnclosingPosition:tapPosition withGranularity:UITextGranularityLine inDirection:UITextLayoutDirectionRight];
NSString *tappedLine = [textView textInRange:textRange];
NSLog(@"%@", tappedLine);
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self resizeView];
}
- (void)resizeView{
//This is where size of view is changed in response to quantity of text in viewwillappear
CGFloat fixedWidth = myView.frame.size.width;
//MAXFLOAT IS THE maximum float system allows
CGSize newSize = [myView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = myView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
myView.frame = newFrame;
[self->myView sizeToFit];
self->myView.editable = NO;
self->myView.scrollEnabled=NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
//This is how the recognizer is created in viewdidload:
UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc]initWithTarget:self
action:@selector(handleTap:)];
//tapList.cancelsTouchesInView = NO;
[self->myView addGestureRecognizer:tapRec];
NSArray* someTexts = @[@"text1, text1, text1, text1, text1, text1, text1, text1, text1, text1",
@"text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2, text2",
@"text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, text3, ",
];
static NSInteger textIndex = 0;
timer = [NSTimer scheduledTimerWithTimeInterval:7.0 repeats:YES block:^(NSTimer * timer){
self->myView.text = someTexts[textIndex];
[self resizeView];
textIndex ++;
if (textIndex >= someTexts.count) {
textIndex = 0;
}
}];
}
@end
Upvotes: 1