简体   繁体   English

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

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

I'm using custom UITableViewCell s inside my UITableView .我在UITableViewCell使用自定义UITableView Each of these UITableViewCell s is pretty high and contains a UITextField at the top.这些UITableViewCell的每一个都非常高,并且在顶部包含一个UITextField

When a user taps the UITextField in order to edit it, a keyboard appears and the UITableView scrolls automatically so that the cell is at the top of the screen.当用户点击UITextField以对其进行编辑时,会出现一个键盘并且UITableView自动滚动,以便单元格位于屏幕顶部。

The problem is that this scrolls the UITableView to the bottom of the UITableViewCell , not the top.问题是,这种滚动UITableView在底部UITableViewCell ,不上头。 When the UITableViewCell is high and edited the UITextField is at the top so you can't see the UITextField .UITableViewCell高并且编辑时UITextField位于顶部,因此您看不到UITextField I know how to scroll the UITableView programmatically, but I just don't know how to disable this automatic scrolling so that I can scroll the UITableView on my own.我知道如何以编程方式滚动UITableView ,但我只是不知道如何禁用这种自动滚动,以便我可以自己滚动UITableView How can I do this?我怎样才能做到这一点?

The autoscroll-behavior is located in the UITableViewController functionality. autoscroll-behavior 位于UITableViewController功能中。

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.使用UIViewController代替UITableViewController - 自行设置数据源和委托。
  2. Override the viewWillAppear method and don't call [super viewWillAppear: animated]覆盖viewWillAppear方法,不要调用[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:使用这两种解决方案,您不仅可以禁用 Autoscroll,还可以禁用其他一些不错但不是必需的功能,这些功能在 Apple 的类参考概述中有所描述:

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

Define properties for your UITableViewController :为您的UITableViewController定义属性:

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

Before you call becomeFirstResponder :在调用becomeFirstResponder之前:

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

Add the following code to your table view controller:将以下代码添加到您的表视图控制器:

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

After you call resignFirstResponder , set scrollDisabled = NO .调用resignFirstResponder ,设置scrollDisabled = NO

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然后实现这个 UIScrollViewDelegate 方法

- (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.但请注意,如果用户点击 UITextField 中将被键盘覆盖的位置,则它不会滚动。

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

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) .最好的方法是UITableView然后覆盖setContentOffset(_ contentOffset: CGPoint, animated: Bool)而不是调用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
}

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

Unfortunately, overriding -viewWillAppear: doesn't work for me in iOS 8.不幸的是,在 iOS 8 中覆盖 -viewWillAppear: 对我不起作用。

Here is my solution (as in UITableViewController implementation):这是我的解决方案(如 UITableViewController 实现):

- (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.由于自动滚动行为是由 UIKeyboard 的显示/隐藏通知调用的,所以不要观察它们。

Did you try to set "scrollsToTop" - tableview's property to NO.您是否尝试将“scrollsToTop” - tableview 的属性设置为 NO。 By default it is YES.默认情况下是 YES。

You can try doing the following:您可以尝试执行以下操作:

self.tableView.scrollEnabled = NO;

This should disable the scrollview in the tableview.这应该禁用 tableview 中的滚动视图。

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

相关问题 如何在编辑uitextfield时停止在uitableview中滚动 - how to stop scrolling in uitableview while editing uitextfield 在具有自动高度的 UITableViewCell 中添加 UITableView - Add UITableView inside UITableViewCell with automatic height 为什么UITextField作为自定义UITableViewCell的子视图会阻止父UITableView的滚动? - Why does a UITextField as a subview of a custom UITableViewCell inhibit the scrolling of the parent UITableView? 滚动时,UITableViewCell复制UITextfield子视图 - UITableViewCell duplicating UITextfield subviews when scrolling 使用UITableViewCell和UITextField滚动问题 - Scrolling Issue with UITableViewCell and UITextField 编辑和滚动时UITableViewCell内容不正确 - UITableViewCell content incorrect when editing and scrolling 当UITableView滚动时,UITableViewCell动画停止 - UITableViewCell animations stop when UITableView is scrolling UITableView滚动时如何维护UITableViewCell状态? - How to maintain UITableViewCell state when UITableView scrolling? 如何在UITableView(UITableViewCell)中使用UITextField实现类似的UI? - How to achieve similar UI with UITextField inside UITableView (UITableViewCell)? 带有部分的UITableViewCell内的iOS 6 UITextField在滚动时获取错误的数据 - iOS 6 UITextField inside UITableViewCell with sections get wrong data on scrolling
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM