Cursor Outside UITextView

I searched high and low and did not seem to find an answer. The closest I've seen is here: UITextView cursor under frame when changing frame

Sorry, there are no screenshots since I (almost) have no reputation, but it looks like a related SO record.

When I run the application on iOS6, everything works fine (the content scrolls with the cursor to save it on the screen), but on iOS7 the cursor goes one line beyond the UITextView. I tried adding UIEdgeInsets to move the content, but when the user actively enters text, he simply adds a new line until the cursor is below the end of the text view.

My layout consists of a shortcut (headerText) with a UITextView (textView) below it. This view is shown in the tab bar. A keyboard addition is added, but the height is automatically calculated to the height of the keyboard before calling the function.

Here is the function I use to resize my views invoked from the keyboard show / hide delegate, rotate, initial layout, etc.:

-(void)resizeViewsWithKbdHeight:(float)kbHeight { //set the header label frame //set constraints //total view width - 30 (15 each for left and right padding) CGFloat labelWidth = ([[[self navigationController] view] bounds].size.width - 30); CGSize constraintSize = {labelWidth, CGFLOAT_MAX}; //calculate needed height for header label CGSize textSize = [[self headerText] sizeWithFont:[UIFont systemFontOfSize:17.0f] constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping]; //build and set frame for header label: //make it the same as the old CGRect headerTempSize = [[self headerLabel] frame]; //except for the height headerTempSize.size.height = textSize.height; //and set it [[self headerLabel] setFrame:headerTempSize]; //correct the placement of the UITextView, so it under the header label //build a new frame based on current textview frame CGRect newFrame = [[self textView] frame]; //get the y position of the uitextview, the +8 is the padding between header and uitextview CGFloat vertPadding = [[self headerLabel] frame].origin.y + [[self headerLabel] frame].size.height + 8; //bump it down vertically newFrame.origin.y = vertPadding; //bump things down by the amount of the navigation bar and status bar float offscreenBump = [[[self navigationController] navigationBar] frame].origin.y + [[[self navigationController] navigationBar] frame].size.height; //if we aren't showing the keyboard, add the height of the tab bar if(kbHeight == 0) { offscreenBump += [[[self tabBarController] tabBar] frame].size.height; } //calculate the new height of the textview, the +9 is for padding below the text view CGFloat newHeight = [[[self navigationController] view] bounds].size.height - ([[self textView] frame].origin.y + 9 + kbHeight + offscreenBump); //resize the height as calculated newFrame.size.height = newHeight; //set textview frame to this new frame [[self textView] setFrame:newFrame]; } 

I am trying to support iOS5, so there is no AutoLayout.

Perhaps I am incredibly naive in what I do.

Thanks in advance!

+7
ios ios7 uitextview uiedgeinsets
source share
2 answers

This seems like a bug in iOS 7. The only way I found to fix this problem is to add a delegate for the UITextView and implement textViewDidChangeSelection , resetting the view to show the selection as follows:

 #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) - (void) textViewDidChangeSelection: (UITextView *) tView { if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { [tView scrollRangeToVisible:[tView selectedRange]]; } } 
+7
source share

I found the hacker an even more efficient way to solve the problem:

 - (void)textViewDidChangeSelection:(UITextView *)textView { if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { if ([textView.text characterAtIndex:textView.text.length-1] != ' ') { textView.text = [textView.text stringByAppendingString:@" "]; } NSRange range0 = textView.selectedRange; NSRange range = range0; if (range0.location == textView.text.length) { range = NSMakeRange(range0.location - 1, range0.length); } else if (range0.length > 0 && range0.location + range0.length == textView.text.length) { range = NSMakeRange(range0.location, range0.length - 1); } if (!NSEqualRanges(range, range0)) { textView.selectedRange = range; } } } 

Basically, I'm sure there is always a finite space in the text box. Then, if the user tries to change the selection so that the space is open, change the selection. Always keeping a space in front of the cursor, the field scrolls as it should.

Finally, if you need to, remove the trailing space when copying text to your model (not shown).

+6
source share

All Articles