I've searched high and low and can't seem to find an answer. The closest thing I've seen is here: UITextView cursor below frame when changing frame
Sorry, no screenshots as I have (nearly) no reputation, but it looks similar to the linked SO post.
When I run the app on iOS6, things work perfectly (content scrolls with the cursor to keep it on screen), but on iOS7, the cursor goes one line beyond the end of the UITextView. I tried adding UIEdgeInsets to move the content, but when the user is actively entering text, it just keeps adding a new line until the cursor is below the end of the text view.
My layout consists of a Label (headerText) with a UITextView (textView) below it. This view is shown from a tab bar. There is a keyboard input accessory that is added, but it's height is calculated into the keyboard height automatically before the function is called.
Here is the function I use to resize my views, called from 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's 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'm trying to support for iOS5, so no AutoLayout.
It's possible I'm being incredibly naive about how I'm doing things.
Thanks in advance!
EKKeyboardAvoiding
. If you want to try, that would be fine. It will resize the scrollview as you need when keyboard invokes. You can use that for any scrollview subclasses. – Tune