Disabling automatic scrolling of UITableView when editing UITextField inside UITableViewCell

后端 未结 9 826
别跟我提以往
别跟我提以往 2020-11-30 00:40

I\'m using custom UITableViewCells inside my UITableView. Each of these UITableViewCells is pretty high and contains a UITextFie

相关标签:
9条回答
  • 2020-11-30 00:48

    The issue for me was not so much that it scrolled but that it took the text view being edited off the screen.

    So instead of preventing the scrolling, I just rescroll the tableview to where I want when the editing is triggered, like this:

    public func textViewShouldBeginEditing(textView: UITextView) -> Bool {            
      dispatch_async(dispatch_get_main_queue()) {
        tableViewController.tableView.scrollToRowAtIndexPath(self.indexPath!, atScrollPosition: UITableViewScrollPosition.Middle, animated: true)
      }
      return true
    }
    
    0 讨论(0)
  • 2020-11-30 00:50

    Unfortunately, overriding -viewWillAppear: doesn't work for me in iOS 8.

    Here is my solution (as in UITableViewController implementation):

    - (void)viewDidLoad {
    
    [super viewDidLoad];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self.tableView name:UIKeyboardWillShowNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self.tableView name:UIKeyboardWillHideNotification object:nil];
    }
    

    Since the auto-scrolling behaviour is invoked by UIKeyboard's show/hide notifications, so just NOT observe them.

    0 讨论(0)
  • 2020-11-30 01:00

    Did you try to set "scrollsToTop" - tableview's property to NO. By default it is YES.

    0 讨论(0)
  • 2020-11-30 01:01

    The best way is to subclass UITableView and then override setContentOffset(_ contentOffset: CGPoint, animated: Bool) and not to call super.setContentOffset(_ contentOffset: CGPoint, animated: Bool). In this method is where the view controller is doing the automatic scroll.

    override func setContentOffset(_ contentOffset: CGPoint, animated: Bool)
    {
        //Do nothing
    }
    
    0 讨论(0)
  • 2020-11-30 01:04

    You can do the following:

    - (void)registerForKeyboardNotifications
    {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillShow:)
                                                     name:UIKeyboardWillShowNotification object:nil];
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardDidShow:)
                                                     name:UIKeyboardDidShowNotification object:nil];
    }
    
    - (void)unregisterForKeyboardNotifications
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];
    }
    
    - (void)keyboardWillShow:(NSNotification *)notification
    {
        self.tableView.scrollEnabled = NO;
    }
    
    - (void)keyboardDidShow:(NSNotification *)notification
    {
        double delayInSeconds = 0.3;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
                self.tableView.scrollEnabled = YES;
        });
    }
    

    Then implement this UIScrollViewDelegate method

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        if (! self.tableView.scrollEnabled)
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
    }
    

    !!! But be warned, that if the user taps in a location in the UITextField that will be covered by the Keyboard, then it won't scroll.

    From my point of view, the best thing to do is to make sure that all the cells from top to then one with the UITextField included, will be visible when then Keyboard will show.

    0 讨论(0)
  • 2020-11-30 01:06

    The autoscroll-behavior is located in the UITableViewController functionality.

    To disable the automatic scrolling I found two ways:

    1. Use instead of the UITableViewController simply a UIViewController - set the datasource and delegate on your own.
    2. Override the viewWillAppear method and don't call [super viewWillAppear: animated]

    With both solution you disable not only the Autoscroll, but also some other nice but not essential features, that are described in the overview of Apple´s class reference:

    https://developer.apple.com/documentation/uikit/uitableviewcontroller

    0 讨论(0)
提交回复
热议问题