在UITableViewCell中编辑UITextField时禁用UITableView的自动滚动function

我在我的UITableView使用自定义的UITableView 。 这些UITableViewCell的每一个都非常高,在顶部包含一个UITextField

当用户点击UITextField进行编辑时,会出现一个键盘, UITableView自动滚动,以使单元位于屏幕的顶部。

问题是这个UITableView滚动到UITableView的底部,而不是顶部。 当UITableViewCell高和编辑时, UITextField在顶部,所以你不能看到UITextField 。 我知道如何以编程方式滚动UITableView ,但我只是不知道如何禁用自动滚动,以便我可以自己滚动UITableView 。 我怎样才能做到这一点?

自动滚动行为位于UITableViewControllerfunction中。

要禁用自动滚动,我find了两种方法:

  1. 使用UITableViewController而不是简单的UIViewController – 自己设置数据源和委托。
  2. 重写viewWillAppear方法,不要调用[super viewWillAppear: animated]

使用这两种解决scheme,您不仅可以禁用自动滚动function,还可以禁用苹果类别参考概述中描述的其他一些很好但不重要的function:

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

为你的UITableViewController定义属性:

 @property (nonatomic) BOOL scrollDisabled; @property (nonatomic) CGFloat lastContentOffsetY; 

在你打电话给becomeFirstResponder之前:

 // Save the table view's y content offset lastContentOffsetY = tableViewController.tableView.contentOffset.y; // Enable scrollDisabled scrollDisabled = YES; 

将以下代码添加到您的表视图控制器:

 -(void)scrollViewDidScroll:(UIScrollView *)scrollView { if (self.scrollDisabled) { [self.tableView setContentOffset:CGPointMake(0, lastContentOffsetY)]; } ... } 

在你调用resignFirstResponder ,设置scrollDisabled = NO

您可以执行以下操作:

 - (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; }); } 

然后实现这个UIScrollViewDelegate方法

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

! 但是要注意的是,如果用户在键盘覆盖的UITextField中点击一个位置,那么它将不会滚动。

从我的angular度来看,最好的办法是确保从UITextField包含的所有单元格到顶部的单元格在键盘显示时都可以看到。

对我来说问题不是滚动,而是把文本视图从屏幕上编辑出来。

所以,而不是防止滚动,我只是resview的tableview到我想要的,当编辑触发,如下所示:

 public func textViewShouldBeginEditing(textView: UITextView) -> Bool { dispatch_async(dispatch_get_main_queue()) { tableViewController.tableView.scrollToRowAtIndexPath(self.indexPath!, atScrollPosition: UITableViewScrollPosition.Middle, animated: true) } return true } 

不幸的是,重写-viewWillAppear:在iOS 8中不适用于我。

这是我的解决scheme(如在UITableViewController实现):

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

由于自动滚动行为是由UIKeyboard的显示/隐藏通知调用的,所以不要观察它们。

最好的方法是UITableView ,然后重写setContentOffset(_ contentOffset: CGPoint, animated: Bool)而不是调用super.setContentOffset(_ contentOffset: CGPoint, animated: Bool) 。 在这个方法中,视图控制器正在进行自动滚动。

 override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) { //Do nothing } 

你有没有尝试将“scrollsToTop” – tableview属性设置为NO。 默认情况下是YES。

您可以尝试执行以下操作:

 self.tableView.scrollEnabled = NO; 

这应该禁用tableview中的滚动视图。