2012-03-09 98 views
43

我在我的UITableView中使用自定义UITableViewCell。这些UITableViewCell中的每一个都非常高,并在顶部包含UITextField在UITableViewCell中编辑UITextField时禁用UITableView的自动滚动

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

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

+0

你明白这一点吗?遇到同样的问题。 – 2012-03-23 18:40:17

+0

@SteveBaughman你找到解决方案吗? – HighFlyer 2012-11-07 10:36:25

+0

nope :(我实际上停止使用表视图,因为这个和其他一些原因...:/ – 2012-11-07 15:23:17

回答

59

自动滚动行为位于UITableViewController功能。

要禁用自动滚动,我发现有两种方式:

  1. 使用,而不是简单地UITableViewController一个UIViewController - 设定你自己的数据源和委托。
  2. 重写viewWillAppear方法,不叫[super viewWillAppear: animated]

使用这两种解决方案,您禁用不仅自动滚动,但也有一些其他的不错,但不是必需的功能,在Apple's类的概要描述参考:

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

+3

我有同样的问题和解决方案2工作。我已经在iOS 5.0.0及以上版本中测试过,目前为止(当前版本为6.1.2)。不支持4,但嘿,这是2013年,所以我们可以说5.0是目前支持的最低版本。 – Cocoadelica 2013-03-01 09:53:28

+0

问题在于插入内容不适合容纳键盘,至少在iOS 7.0中不适用。 6.这意味着需要更多代码来手动执行此操作:捕捉键盘通知,......难看 – 2014-03-05 20:41:49

+0

选项2与我合作,谢谢 – 2014-04-27 23:15:53

-2

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

+0

尝试过它,但它没有工作... scrollToTop doesn'不管怎么处理...谢谢你的回答! – 2012-03-10 18:53:18

-4

你可以尝试做如下:

self.tableView.scrollEnabled = NO; 

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

+1

这并不妨碍自动滚动UITableViewController时,在UITableViewCell中的文本字段上轻击时会做什么。 – Gujamin 2012-11-28 19:46:30

3

你可以做到以下几点:

- (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的顶部到另一个的单元格在键盘显示时将可见。

+0

You da man art。谢谢,工作。 – 2014-11-19 00:08:20

+0

-scrollViewDidScroll:确实在自动滚动发生时调用,这里是最好的解决方案 – 2015-07-15 11:32:04

6

定义属性您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,s et scrollDisabled = NO

+0

这不是scrollview问题,是tableViewController类。正确的答案是覆盖viewWilAppear – 2017-08-02 12:49:21

1

这个问题对我来说并不是很大,它滚动,但它是从屏幕上编辑文本视图。

因此,而不是防止滚动,我只是rescroll的实现代码如下的地方,我希望在编辑被触发,这样的:

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

不幸的是,覆盖-viewWillAppear:不为我在工作的iOS 8.

这里是我的解决方案(如在实施的UITableViewController):

- (void)viewDidLoad { 

[super viewDidLoad]; 

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

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

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

+0

这仍然适合你?无法在iOS 11/Xcode 9中使用它 – simonthumper 2017-10-30 11:29:12

1

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

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