繁体   English   中英

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

[英]Disabling automatic scrolling of UITableView when editing UITextField inside UITableViewCell

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

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

问题是,这种滚动UITableView在底部UITableViewCell ,不上头。 UITableViewCell高并且编辑时UITextField位于顶部,因此您看不到UITextField 我知道如何以编程方式滚动UITableView ,但我只是不知道如何禁用这种自动滚动,以便我可以自己滚动UITableView 我怎样才能做到这一点?

autoscroll-behavior 位于UITableViewController功能中。

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

  1. 使用UIViewController代替UITableViewController - 自行设置数据源和委托。
  2. 覆盖viewWillAppear方法,不要调用[super viewWillAppear: animated]

使用这两种解决方案,您不仅可以禁用 Autoscroll,还可以禁用其他一些不错但不是必需的功能,这些功能在 Apple 的类参考概述中有所描述:

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 中将被键盘覆盖的位置,则它不会滚动。

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

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

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

对我来说,问题不在于它滚动,而是将正在编辑的文本视图从屏幕上移开。

因此,我没有阻止滚动,而是在触发编辑时将 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
}

您可以禁用自动内容插入调整,如下所示:

tableView.contentInsetAdjustmentBehavior = .never

不幸的是,在 iOS 8 中覆盖 -viewWillAppear: 对我不起作用。

这是我的解决方案(如 UITableViewController 实现):

- (void)viewDidLoad {

[super viewDidLoad];

[[NSNotificationCenter defaultCenter] removeObserver:self.tableView name:UIKeyboardWillShowNotification object:nil];

[[NSNotificationCenter defaultCenter] removeObserver:self.tableView name:UIKeyboardWillHideNotification object:nil];
}

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

您是否尝试将“scrollsToTop” - tableview 的属性设置为 NO。 默认情况下是 YES。

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

self.tableView.scrollEnabled = NO;

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM