滚出屏幕

时间:2016-01-18 13:24:02

标签: ios swift uitableview uitextview

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

我认为一个很好的解决方案是,当单元格在屏幕外时,为resignFirstResponder调用UITextView。但是,在这种情况下似乎没有调用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

2 个答案:

答案 0 :(得分:0)

UIGestureRecognizer添加到UITableview方法中的viewDidLoad

    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
  }

答案 1 :(得分:0)

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

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

private var currentFirstResponderIndexPath:NSIndexPath? = nil

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

在我的自定义UITableViewCell中:

//MARK: - UITextViewDelegate

public func textViewDidEndEditing(textView: UITextView)
{
    //....
    agendaViewController?.didSetFirstResponderIndexPath(nil)
}


public func textViewDidBeginEditing(textView: UITextView)
{
    //...
    agendaViewController?.didSetFirstResponderIndexPath(indexPath)
}

其中agendaViewController是一个指向viewController的弱指针。这也可以是代表。

然后我检查滚动它时当前的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)
        }
    }
}

然而,这种解决方案确实有一些缺点。如果开始编辑tableview底部的一行,它将显示键盘并隐藏将取消第一响应者的单元格,这将隐藏键盘等。那里需要更多的逻辑。