在UITableViewCell中编辑UITextField时禁用UITableView的自动滚动function
我在我的UITableView
使用自定义的UITableView
。 这些UITableViewCell
的每一个都非常高,在顶部包含一个UITextField
。
当用户点击UITextField
进行编辑时,会出现一个键盘, UITableView
自动滚动,以使单元位于屏幕的顶部。
问题是这个UITableView
滚动到UITableView
的底部,而不是顶部。 当UITableViewCell
高和编辑时, UITextField
在顶部,所以你不能看到UITextField
。 我知道如何以编程方式滚动UITableView
,但我只是不知道如何禁用自动滚动,以便我可以自己滚动UITableView
。 我怎样才能做到这一点?
自动滚动行为位于UITableViewController
function中。
要禁用自动滚动,我find了两种方法:
- 使用
UITableViewController
而不是简单的UIViewController
– 自己设置数据源和委托。 - 重写
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中的滚动视图。