【问题标题】:UITableView tap not working first time after constraints change约束更改后 UITableView 水龙头第一次不工作
【发布时间】:2018-04-15 10:43:23
【问题描述】:

重要提示:我的问题不在于我实施的是 didDeelectRowAt 而不是 didSelectRowAt。已经检查过了:)

我有一个UITableView,它显示在模态显示的视图控制器的部分屏幕上。当用户拖动它时,它会调整到全屏并返回到某个定义的最小高度。我通过从UIScrollViewDelegate 实现以下方法来做到这一点:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    guard !scrollView.isDecelerating else { return }

    let contentOffset = scrollView.contentOffset.y
    if tableViewHeightConstraint.constant < view.frame.height && contentOffset > 0.0 {
        tableViewHeightConstraint.constant = min(contentOffset + tableViewHeightConstraint.constant, view.frame.height)
        scrollView.contentOffset.y = 0.0
        return
    }

    if tableViewHeightConstraint.constant > minViewHeight && contentOffset < 0.0 {
        tableViewHeightConstraint.constant = max(tableViewHeightConstraint.constant + contentOffset, minViewHeight)
        scrollView.contentOffset.y = 0.0
    }
}

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    // Here I have some calculations if depending the dragging end position and the velocity the end size should be full screen or `minViewHeight`
    // After calculating what the end size should be I'm animating the size change
    heightConstraint.constant = newConstraintHeight
    UIView.animate(withDuration: TimeInterval(calculatedAnimationDuration), delay: 0.0, options: .curveEaseOut, animations: {
        self.view.layoutIfNeeded()
    }, completion: nil)
}

关于调整大小和滚动的一切工作正常,但有一个问题我无法弄清楚为什么会发生这种情况。如下:

  • 当带有表格视图的视图控制器第一次以最小高度显示并且我点击一个单元格时,它可以正常工作。
  • 如果我拖动以将表格视图扩展到全屏高度并点击一个单元格,它仍然可以正常工作。
  • 如果我拖动以将表格视图扩展到全屏高度,然后再次拖动以将其返回到最小高度,然后点击单元格,则没有任何反应,根本不会调用 UIScrollViewDelegateUITableViewDelegate 方法.如果我再次点击一个单元格,一切正常。

我注意到的一件事是,在将表格视图拖回最小高度后,滚动指示器并没有隐藏。第一次点击它隐藏,第二次点击didSelectRowAt 被调用。

更新:

这里是该问题的测试仓库:https://github.com/nikmin/DragTest

如果拖动不完美,请不要介意,我只是放了一些东西让任何人都可以尝试,但我认为问题很容易重现。

还有一件事...如果您从全尺寸一直拖动到底部以使表格视图达到最小高度并继续拖动以使内容偏移

【问题讨论】:

  • 第一次(未注册)触摸后滚动指示器是否消失?
  • @Luzo 是的,确实如此
  • @nikmin 你能提供一个调试仓库吗?我认为为yoi找到问题会更容易更快。
  • @trungduc 我添加了repo,请看一下
  • @nikmin 我已经为您的问题添加了答案,如果可行,请告诉我;)

标签: ios swift uitableview uiscrollview uiscrollviewdelegate


【解决方案1】:

在试图找出解决方案但没有结果后,我们(我和 UX 设计师)决定稍微改变一下行为。

所以在我正在实现的应用程序的实际场景中,表格视图位于另一个视图中,该视图也有一个标题标签和表格视图上方的一些其他视图。我们决定向这个根视图添加一个平移手势识别器,并在视图具有最小尺寸时禁用表格视图的滚动。这样,只要用户尝试拖动视图内的任何位置(包括表格视图),平移手势识别器就会接管,因此视图的扩展工作。并且单元格中的水龙头仍然有效。

当视图具有最大高度时,表格视图滚动被启用,以便用户可以滚动。这种方法的缺点是当用户滚动到表格视图的顶部并继续滚动时,视图不会减小大小。但是他仍然可以选择通过拖动表格视图上方的任何视图来将其向下拖动。这样往下拉的时候,只有table view的大小发生变化,内容偏移没有变化,这是问题的根源(两者同时变化)。

【讨论】:

    【解决方案2】:

    拖动TableView将其返回到最小高度,然后点击一个单元格,没有任何反应,因为:

    • 当您拖动以将表格视图展开到全屏时,scrollView.isDeceleratingtrue。所以scrollViewDidScroll方法里面的代码会运行。

    • 但是当你拖动TableView使其返回到最小高度时,scrollViewDidScroll就是false。所以scrollViewDidScroll 方法中的代码不会运行。它使第一次点击什么都不做。

    只需从scrollViewDidScroll 中删除guard !scrollView.isDecelerating else { return }。向下拖动TableView后,您将正常点击单元格。

    但你需要稍微改变一下逻辑,删除上面的行后动画会出错。

    希望对你有帮助;)

    【讨论】:

    • 据我测试,问题不在于scrollViewDidScroll,因为在我释放拖动手势后它根本没有被调用。因此,当向下拖动以折叠视图时,scrollViewWillEndDragging 是我将手指从屏幕上移开后的最后一个调用,而scrollViewDidScroll 则根本不会调用它。 guard !scrollView.isDecelerating 只是在高度约束没有改变的情况下正常的表格视图滚动的情况下需要。
    • @nikmin 您只需要评论guard !scrollView.isDecelerating else { return } 并尝试在下拉后单击单元格。让我们先试试。我确定您可以单击单元格。
    • 为什么你认为我没有尝试过? :) 我在这个问题上纠结了太久,我已经尝试了我能想到的一切。仅当您将其一直拖到最小高度以下然后释放时,向下拖动才有效。但是如果你在它到达最小高度之前滑动并释放,但它继续移动到最小高度(scrollViewWillEndDragging 中的动画),这是同一回事。我尝试通过评论guard 并更改scrollViewDidScroll 中的逻辑中的一些内容来尝试此操作。但没有任何帮助:(
    • 很抱歉@nikmin,我的错误。不记得为什么当我发布答案时它会起作用。我将尝试进行更多调查以帮助您。
    • 非常感谢您的帮助,但正如我在下面的答案中发布的那样,我们决定稍微改变行为以避免此错误。花太多时间试图找到解决方案 :) 如果你碰巧遇到了这个问题的解决方案,我会很高兴听到并尝试它
    【解决方案3】:

    看起来内容偏移设置不正确。第一次触摸取消了不正确的位置(取消滚动),这就是它没有注册的原因。如果我们能访问完整的代码来检查它可能会更好,因为我无法告诉你问题到底出在哪里,但我猜它在方法 scrollViewDidScroll 中。

    【讨论】:

    • scrollViewDidScroll 的整个代码以及与表格视图相关的所有其他内容都在问题中的代码 sn-p 中。但我会尝试用这个东西创建一个小仓库。如果您还有其他想法,请分享,我愿意尝试任何事情:)
    • 我添加了repo,请看一下
    • 不幸的是,我只是来这里的...如果对您有帮助,则会调用 didHighlight。如果没有人会找到解决方案,那么我会尝试使用自定义手势识别器来实现它,值得一试
    猜你喜欢
    • 2021-04-15
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    相关资源
    最近更新 更多