2
votes
[self.scrollView scrollRectToVisible:textField.bounds animated:YES];

I can't seem to get my UIScrollView to scroll at all so that it doesn't obscure my UITextField. I thought that scrollRectToVisible would be my savior but it looks like a no go. Maybe I'm missing something like translating the coordinates of my textField to my scrollView. Either way check out my sample project.

https://github.com/stevemoser/Programming-iOS-Book-Examples/tree/master/ch20p573scrollViewAutoLayout2

Oh, and this project might be missing the delegate connection but I checked that and it still doesn't scroll.

I've seen other questions similar to this but none that mention Autolayout.

2
TPKeyboardAvoidingScrollView solved the issue but I don't want to use a whole third party class when a line or two will fix it.Steve Moser
I have added one EDIT in my answer. Just check for that possibility if it is not the case.Bhavin

2 Answers

8
votes

I was having issues with scrollRectToVisible:: as well after converting to Auto Layout. I just changed it to a direct call to setContentOffset:: and it started working again.

0
votes

I had the same problem, I wanted to scroll an autolayouted UITextEdit into view without making it the first responder.

For me the issue was that the bounds of the UITextField were set later on during the auto layout pass, so if you do it immediately after setting up the layout the bounds are not valid yet.

To workaround I did create a descendant of UITextField, did overwrite setBounds: and added a 0 timer to scroll into view "later on" (You can't scroll in that moment because the auto layout pass of the system might no be finished at that point)

@interface MyTextField: UITextField
{
  bool _scrollIntoView;
}
..
@end
@implementation MyTextField
-(void)setBounds:(CGRect)bounds
{
  bool empty=CGRectIsEmpty(self.bounds);
  bool isFirstResponder=self.isFirstResponder;
  [super setBounds:bounds];
  if (empty && !isFirstResponder && _scrollIntoView) 
    [self performSelector:@selector(scrollIntoViewLater) withObject:nil afterDelay:0];
  else if (empty && isFirstResponder)
    [self performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0];
}

-(void)scrollIntoViewLater
{
  CGRect r=[scrollView convertRect:self.bounds fromView:self];
  [scrollView scrollRectToVisible:r animated:TRUE];
}
@end

If the field should be additionally editable with the on screen keyboard, simply call becomeFirstResponder later on: it scrolls automagically into view above the keyboard using the private scrollTextFieldToVisible API which in turn calls scrollRectToVisible:animated: of the scrollview.

Your sample link is broken btw...