Disable UIScrollView scrolling when UITextField be

2019-01-03 23:58发布

When a UITextField, embedded in a UIScrollView becomes first responder, by lets say the user typing in some character, the UIScrollView scrolls to that Field automatically, is there any way to disable that?

Duplicate rdar://16538222 over

11条回答
▲ chillily
2楼-- · 2019-01-04 00:42

Building on Luke's answer, to handle the issue that his solution completely disables auto-scroll, you can disable it selectively as follows:

//  TextFieldScrollView
#import <UIKit/UIKit.h>

@interface TextFieldScrollView : UIScrollView

@property (assign, nonatomic) IBInspectable BOOL preventAutoScroll;

@end

@implementation TextFieldScrollView

- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated {
    if (self.preventAutoScroll == NO) {
        [super scrollRectToVisible:rect animated:animated];
    }
}

@end

This way, you can completely set it up in Interface Builder to disable the auto-scroll, but have full control at any time to re-enable it (though why you'd want to is beyond me).

查看更多
3楼-- · 2019-01-04 00:42

An easier way to stop the scrollview scrolling when you select a textField is in your viewController::viewWillAppear() DO NOT call [super viewWillAppear];

You can then control the scroll as you wish.

查看更多
4楼-- · 2019-01-04 00:47

I've tried @TaketoSano's answer, but seems not works.. My case is that I don't have a scrollview, just a view with several text fields.

And finally, I got a workaround. There're two default notification names for keyboard that I need:

  • UIKeyboardDidShowNotification when the keyboard did show;
  • UIKeyboardWillHideNotification when the keyboard will hide.

Here's the sample code I used:

- (void)viewDidLoad {
  [super viewDidLoad];

  ...

  NSNotificationCenter * notificationCetner = [NSNotificationCenter defaultCenter];
  [notificationCetner addObserver:self
                         selector:@selector(_keyboardWasShown:)
                             name:UIKeyboardDidShowNotification
                           object:nil];
  [notificationCetner addObserver:self
                         selector:@selector(_keyboardWillHide:)
                             name:UIKeyboardWillHideNotification
                           object:nil];
}

- (void)_keyboardWasShown:(NSNotification *)note {
  [self.view setFrame:(CGRect){{272.f, 55.f}, {480.f, 315.f}}];
}

- (void)_keyboardWillHide:(NSNotification *)note {
  [self.view setFrame:(CGRect){{272.f, 226.5f}, {480.f, 315.f}}];
}

Here, the (CGRect){{272.f, 226.5f}, {480.f, 315.f}} is view's default frame when keyboard is hidden. And (CGRect){{272.f, 55.f}, {480.f, 315.f}} is view's frame when keyboard did show.

And b.t.w., the view's frame changing will be applied animation automatically, this's really perfect!

查看更多
闹够了就滚
5楼-- · 2019-01-04 00:51

As Taketo mentioned, when a UITextField is made first responder, its first parent view that is of type UIScrollView (if one exists) is scrolled to make that UITextField visible. The easiest hack is to simply wrap each UITextField in a UIScrollView (or ideally, wrap all of them in a single dummy UIScrollView). This is very similar to Taketo's solution, but it should give you slightly better performance, and it will keep your code (or your interface in Interface Builder) much cleaner in my opinion.

查看更多
ら.Afraid
6楼-- · 2019-01-04 00:55

I don't know of any property of UIScrollView that would allow that. It would be poor user experience to be able to disable that, IMHO.

That said, it may be possible to subclass UIScrollView and override some of its methods to check that the UITextfield is not a first responder before scrolling.

查看更多
登录 后发表回答