【问题标题】:ResignFirstResponder for UITextView in UITableViewCell when scrolled out of screen滚动出屏幕时 UITableViewCell 中 UITextView 的 ResignFirstResponder
【发布时间】:2016-01-18 13:24:01
【问题描述】:

我有可编辑的自定义(笔尖)加载可重用 UITableViewCells,其中包含 UITextView。行是自定大小的。我有一个问题,如果用户开始编辑 UITextView 然后开始滚动焦点(firstResponder)仍然保留,我认为这是一个问题,因为通常允许删除或重用屏幕单元格。这会导致问题,因此该行仍保留在内存中,并且稍后会显示在错误的位置。

我认为一个好的解决方案是在单元格不在屏幕时为UITextView 调用resignFirstResponder。然而,didEndDisplayingCell 似乎并没有在这种情况下被调用。我也试过prepareForReuse 也没有被调用。

有什么想法吗?

public func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
{
    if (tableView.indexPathsForVisibleRows?.indexOf(indexPath) == nil) {
        if let noteCell = cell as? AgendaNotesTableViewCell {
            noteCell.noteTextView.resignFirstResponder()
        }
    }
}

这似乎适用于所有单元格,除了当前为 firstResponder 的单元格。我猜它保存在内存中,因此从未用于调用didEndDisplayingCell

【问题讨论】:

    标签: ios swift uitableview uitextview


    【解决方案1】:

    viewDidLoad 方法中将UIGestureRecognizer 添加到UITableview

        UITapGestureRecognizer * gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(removeKeyboard)];
        [self.tableView addGestureRecognizer:gesture];
    

    使用UITextView 的其中一种委托方法保留对它的引用

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    

    当点击 tableview 时,手势识别器方法调用,即

    - (void)removeKeyboard {
     // set resignFirstResponder to textview
      }
    

    【讨论】:

    • 这不是我想要的。我假设当您触摸UITableView 上的任何位置时,此代码会隐藏键盘。当单元格滚动到屏幕可见区域之外时,我想隐藏键盘。
    【解决方案2】:

    我想出了一个解决方案。它工作正常,但如果有人找到更好的,我会将那个标记为正确的。

    我在视图控制器中添加了一个变量来跟踪 firstResponder UITextView 的当前 indexPath。每次我开始编辑 UITextView 时,我都会在我的 viewController 中使用这个方法设置这个变量:

    private var currentFirstResponderIndexPath:NSIndexPath? = nil
    
    public func didSetFirstResponderIndexPath(indexPath:NSIndexPath?)
    {
        currentFirstResponderIndexPath = indexPath
    }
    

    在我的自定义UITableViewCells 中:

    //MARK: - UITextViewDelegate
    
    public func textViewDidEndEditing(textView: UITextView)
    {
        //....
        agendaViewController?.didSetFirstResponderIndexPath(nil)
    }
    
    
    public func textViewDidBeginEditing(textView: UITextView)
    {
        //...
        agendaViewController?.didSetFirstResponderIndexPath(indexPath)
    }
    

    其中的议程视图控制器是指向视图控制器的弱指针。这也可以是委托。

    然后我在滚动时检查当前的 firstResponder 是否不可见:

    //MARK: - UIScrollViewDelegate
    
    public func scrollViewDidScroll(scrollView: UIScrollView)
    {
        updateHelperAlphas()
        if let indexPath = currentFirstResponderIndexPath {
            let visibleCellIndexPaths = tableView.indexPathsForVisibleRows ?? []
            let indexPathForCellWithFirstResponderIsOutOfScreen = !visibleCellIndexPaths.contains(indexPath)
            if (indexPathForCellWithFirstResponderIsOutOfScreen) {
                self.view.endEditing(true)
            }
        }
    }
    

    但是,这种解决方案确实有一些缺点。如果开始编辑表格视图底部的一行,它将显示键盘并隐藏单元格,该单元格将放弃第一响应者,该响应者将隐藏键盘等。那里需要更多的逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多