约束更改后 UITableView 水龙头第一次不工作
UITableView tap not working first time after constraints change
重要提示: 我的问题不是我正在实施 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)
}
关于调整大小和滚动的一切都很好,但有一个问题,我无法弄清楚为什么会这样。内容如下:
- 当带有 table 视图的视图控制器第一次以最小高度显示时,我点击一个单元格,它工作正常。
- 如果我拖动以将 table 视图扩展到全屏高度并点击一个单元格,它再次正常工作。
- 如果我拖动以将 table 视图扩展到全屏高度,然后再次拖动到 return 它到最小高度,然后点击一个单元格,没有任何反应,没有
UIScrollViewDelegate
或 UITableViewDelegate
方法被调用。如果我再次点击一个单元格,一切正常。
我注意到的一件事是,在将 table 视图拖回到最小高度后,滚动指示器不会隐藏。第一次点击它隐藏,第二次点击 didSelectRowAt
被调用。
更新:
这是问题的测试回购:https://github.com/nikmin/DragTest
如果拖动不完美,请不要介意,我只是放了一些东西让任何人都可以尝试,但我认为这个问题很容易重现。
还有一件事......如果你从全尺寸一直拖到底部所以 table 视图达到最小高度并且你继续拖动所以内容偏移量 < 0 然后你释放,问题没有发生。
看起来内容偏移设置不正确。第一次触摸会取消不正确的位置(取消滚动),这就是它未注册的原因。如果我们可以访问完整代码来检查它可能会更好,因为我不能告诉你问题到底出在哪里,但我想它在方法 scrollViewDidScroll
.
中
将 TableView
拖到 return 到最小高度,然后点击一个单元格,没有任何反应,因为:
当您拖动以将 table 视图展开为全屏时,scrollView.isDecelerating
为 true
。所以 scrollViewDidScroll
方法中的代码将 运行.
但是当你把TableView
拖到return到最小高度时,scrollViewDidScroll
就是false
。所以 scrollViewDidScroll
方法中的代码不会 运行。它让第一次点击什么都不做。
只需从 scrollViewDidScroll
中删除 guard !scrollView.isDecelerating else { return }
。向下拖动TableView
后,您将正常点击单元格。
但是你需要稍微改变一下逻辑,去掉上面那行动画会出错
希望对您有所帮助;)
在尝试找出解决方案但没有结果后,我们(我和一名用户体验设计师)决定稍微改变一下行为。
因此,在我实现此应用程序的真实场景中,table 视图位于另一个视图内,该视图还有一个标题标签和 table 视图上方的一些其他视图。我们决定向这个根视图添加一个平移手势识别器,并在视图具有最小大小时禁用 table 视图的滚动。这样,只要用户试图拖动视图内的任何地方(包括 table 视图),平移手势识别器就会接管,因此视图的扩展有效。单元格中的水龙头仍然有效。
当视图具有最大高度时,table 视图滚动启用,以便用户可以滚动。这种方法的缺点是,当用户滚动到 table 视图的顶部并继续滚动时,视图不会减小大小。但他仍然可以选择通过拖动 table 视图上方的任何视图来将其向下拖动。这样向下拖动时,只有table视图的大小发生变化,内容偏移量没有变化,这是问题的根源(同时改变)。
重要提示: 我的问题不是我正在实施 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)
}
关于调整大小和滚动的一切都很好,但有一个问题,我无法弄清楚为什么会这样。内容如下:
- 当带有 table 视图的视图控制器第一次以最小高度显示时,我点击一个单元格,它工作正常。
- 如果我拖动以将 table 视图扩展到全屏高度并点击一个单元格,它再次正常工作。
- 如果我拖动以将 table 视图扩展到全屏高度,然后再次拖动到 return 它到最小高度,然后点击一个单元格,没有任何反应,没有
UIScrollViewDelegate
或UITableViewDelegate
方法被调用。如果我再次点击一个单元格,一切正常。
我注意到的一件事是,在将 table 视图拖回到最小高度后,滚动指示器不会隐藏。第一次点击它隐藏,第二次点击 didSelectRowAt
被调用。
更新:
这是问题的测试回购:https://github.com/nikmin/DragTest
如果拖动不完美,请不要介意,我只是放了一些东西让任何人都可以尝试,但我认为这个问题很容易重现。
还有一件事......如果你从全尺寸一直拖到底部所以 table 视图达到最小高度并且你继续拖动所以内容偏移量 < 0 然后你释放,问题没有发生。
看起来内容偏移设置不正确。第一次触摸会取消不正确的位置(取消滚动),这就是它未注册的原因。如果我们可以访问完整代码来检查它可能会更好,因为我不能告诉你问题到底出在哪里,但我想它在方法 scrollViewDidScroll
.
将 TableView
拖到 return 到最小高度,然后点击一个单元格,没有任何反应,因为:
当您拖动以将 table 视图展开为全屏时,
scrollView.isDecelerating
为true
。所以scrollViewDidScroll
方法中的代码将 运行.但是当你把
TableView
拖到return到最小高度时,scrollViewDidScroll
就是false
。所以scrollViewDidScroll
方法中的代码不会 运行。它让第一次点击什么都不做。
只需从 scrollViewDidScroll
中删除 guard !scrollView.isDecelerating else { return }
。向下拖动TableView
后,您将正常点击单元格。
但是你需要稍微改变一下逻辑,去掉上面那行动画会出错
希望对您有所帮助;)
在尝试找出解决方案但没有结果后,我们(我和一名用户体验设计师)决定稍微改变一下行为。
因此,在我实现此应用程序的真实场景中,table 视图位于另一个视图内,该视图还有一个标题标签和 table 视图上方的一些其他视图。我们决定向这个根视图添加一个平移手势识别器,并在视图具有最小大小时禁用 table 视图的滚动。这样,只要用户试图拖动视图内的任何地方(包括 table 视图),平移手势识别器就会接管,因此视图的扩展有效。单元格中的水龙头仍然有效。
当视图具有最大高度时,table 视图滚动启用,以便用户可以滚动。这种方法的缺点是,当用户滚动到 table 视图的顶部并继续滚动时,视图不会减小大小。但他仍然可以选择通过拖动 table 视图上方的任何视图来将其向下拖动。这样向下拖动时,只有table视图的大小发生变化,内容偏移量没有变化,这是问题的根源(同时改变)。