簡體   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