tableView 上的 UIPanGestureRecognizer 不滚动 table 个项目
UIPanGestureRecognizer on tableView does not scroll table items
在 UITableView
(Swift 4.0) 上使用 UIPanGesture
拖动 table 视图位置(即原点)。 UIPanGestureRecognizer
检测触摸事件并使用它们。在某些时候,我想将事件委托给 table,这样它就会滚动它的项目。我该怎么做?
我尝试了什么:
@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {
let translation = gestureRecognizer.translation(in: self.view)
// if origin moved to map origin it should not scroll above but cell should scroll normally. But returning does not help scrolling cells
if self.tableView.frame.origin == self.mapContainer.frame.origin && translation.y < 0 {
return
}
var frame = self.tableView.frame
let nHeight = (frame.origin.y + translation.y)
if (nHeight < self.view.frame.size.height) {
frame.origin.y = nHeight
self.tableView.frame = frame
gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
}
}
}
手势已添加到 tableView
let gesture = UIPanGestureRecognizer(target: self, action: #selector(self.tableViewDragged(gestureRecognizer:)))
self.tableView.addGestureRecognizer(gesture)
self.tableView.isUserInteractionEnabled = true
gesture.delegate = self
问题总结:
对于在 tableview 的任何点(即在任何单元格上)的相同平移手势,当 tableviews 原点固定在容器的左上角时,我需要滚动项目。否则我必须移动 table 视图直到它附加到左上角。此外,如果没有什么可以向下滚动,我需要再次移动下面的 table 以进行平移手势。
*问题用例:*
- 初始条件 - table视图原点在屏幕中间,
即 (0, Height/2)
- 向上平移手势 - table 垂直向上移动,但没有项目滚动,直到原点卡在 (0,0)
- 向上平移手势 - 单元格项目向上移动但 table 本身
- 向上平移手势 - 单元格项目向上移动直到单元格末尾
- 向下平移手势 - 单元格项目向下移动直到索引 0,假设来到 0 索引
- 向下平移手势 - table视图垂直向下移动,直到其原点到达屏幕中间(0,Height/2)
我不知道比将 tableView 子类化并在其 layoutSubviews
中阻止其 contentOffset
更好的解决方案。像 :
class MyTableView: UITableView {
var blocksOffsetAtZero = false
override func layoutSubviews() {
super.layoutSubviews()
guard blocksOffsetAtZero else { return }
contentOffset = .zero
}
}
我认为这是地图应用程序中使用的解决方案。当用户在主屏幕上拖动 tableView 时,它不会滚动,而是抬起直到到达屏幕顶部,然后再次滚动。
为此,您向 tableview 添加一个手势,该手势会与 tableView 的识别器同时识别,并在识别器每次移动 tableView 的框架时阻止 tableView 的 contentOffset
。
更新
https://github.com/gaetanzanella/mapLike
你是否正确实现了委托?
// MARK: - UIGestureRecognizerDelegate
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
试试像这样的东西:
@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {
let translation = gestureRecognizer.translation(in: self.view)
var frame = self.tableView.frame
let nHeight = (frame.origin.y + translation.y)
if (nHeight < self.view.frame.size.height) {
frame.origin.y = nHeight
self.tableView.frame = frame
gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
tableView.blocksOffsetAtZero = true
} else {
tableView.blocksOffsetAtZero = false
}
}
}
主要思想:当你改变框架时,阻止滚动。
您也可以使用 kamaldeep singh bhatia 介绍的委托技术,但您将无法先移动 tableView 然后再用一个手势滚动。
看例子here
如果我没理解错的话,你想在滚动时取消PanGesture。
试试这个:
func isItemAvailabe(gesture: UISwipeGestureRecognizer) -> Bool {
if gesture.direction == .down {
// check if we have some values in down if yes return true else false
} else if gesture.direction == .up {
// check if we have some values in up if yes return true else false
}
return false
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.panGesture && otherGestureRecognizer == self.scrollGesture && isItemAvailabe(gesture: otherGestureRecognizer) {
return true
}
return false
}
如果这解决了您的问题或者我没有正确理解,请告诉我。
还记得加上这个:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
您可以查看更多here
最好的方法是使用 tableView 自己的 panGestureRecognizer(不添加新的 gestureRecognizer),例如:
tableView.panGestureRecognizer.addTarget(self, action: #selector(self.tableViewDragged(gestureRecognizer:))
动作
@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {
guard tableView.contentOffset.y < 0 else { return }
if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {
let translation = gestureRecognizer.translation(in: self.view)
// if origin moved to map origin it should not scroll above but cell should scroll normally. But returning does not help scrolling cells
if self.tableView.frame.origin == self.mapContainer.frame.origin && translation.y < 0 {
return
}
var frame = self.tableView.frame
let nHeight = (frame.origin.y + translation.y)
if (nHeight < self.view.frame.size.height) {
frame.origin.y = nHeight
self.tableView.frame = frame
gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
}
}
}
在 UITableView
(Swift 4.0) 上使用 UIPanGesture
拖动 table 视图位置(即原点)。 UIPanGestureRecognizer
检测触摸事件并使用它们。在某些时候,我想将事件委托给 table,这样它就会滚动它的项目。我该怎么做?
我尝试了什么:
@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {
let translation = gestureRecognizer.translation(in: self.view)
// if origin moved to map origin it should not scroll above but cell should scroll normally. But returning does not help scrolling cells
if self.tableView.frame.origin == self.mapContainer.frame.origin && translation.y < 0 {
return
}
var frame = self.tableView.frame
let nHeight = (frame.origin.y + translation.y)
if (nHeight < self.view.frame.size.height) {
frame.origin.y = nHeight
self.tableView.frame = frame
gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
}
}
}
手势已添加到 tableView
let gesture = UIPanGestureRecognizer(target: self, action: #selector(self.tableViewDragged(gestureRecognizer:)))
self.tableView.addGestureRecognizer(gesture)
self.tableView.isUserInteractionEnabled = true
gesture.delegate = self
问题总结:
对于在 tableview 的任何点(即在任何单元格上)的相同平移手势,当 tableviews 原点固定在容器的左上角时,我需要滚动项目。否则我必须移动 table 视图直到它附加到左上角。此外,如果没有什么可以向下滚动,我需要再次移动下面的 table 以进行平移手势。
*问题用例:*
- 初始条件 - table视图原点在屏幕中间, 即 (0, Height/2)
- 向上平移手势 - table 垂直向上移动,但没有项目滚动,直到原点卡在 (0,0)
- 向上平移手势 - 单元格项目向上移动但 table 本身
- 向上平移手势 - 单元格项目向上移动直到单元格末尾
- 向下平移手势 - 单元格项目向下移动直到索引 0,假设来到 0 索引
- 向下平移手势 - table视图垂直向下移动,直到其原点到达屏幕中间(0,Height/2)
我不知道比将 tableView 子类化并在其 layoutSubviews
中阻止其 contentOffset
更好的解决方案。像 :
class MyTableView: UITableView {
var blocksOffsetAtZero = false
override func layoutSubviews() {
super.layoutSubviews()
guard blocksOffsetAtZero else { return }
contentOffset = .zero
}
}
我认为这是地图应用程序中使用的解决方案。当用户在主屏幕上拖动 tableView 时,它不会滚动,而是抬起直到到达屏幕顶部,然后再次滚动。
为此,您向 tableview 添加一个手势,该手势会与 tableView 的识别器同时识别,并在识别器每次移动 tableView 的框架时阻止 tableView 的 contentOffset
。
更新 https://github.com/gaetanzanella/mapLike
你是否正确实现了委托?
// MARK: - UIGestureRecognizerDelegate
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
试试像这样的东西:
@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {
let translation = gestureRecognizer.translation(in: self.view)
var frame = self.tableView.frame
let nHeight = (frame.origin.y + translation.y)
if (nHeight < self.view.frame.size.height) {
frame.origin.y = nHeight
self.tableView.frame = frame
gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
tableView.blocksOffsetAtZero = true
} else {
tableView.blocksOffsetAtZero = false
}
}
}
主要思想:当你改变框架时,阻止滚动。
您也可以使用 kamaldeep singh bhatia 介绍的委托技术,但您将无法先移动 tableView 然后再用一个手势滚动。
看例子here
如果我没理解错的话,你想在滚动时取消PanGesture。
试试这个:
func isItemAvailabe(gesture: UISwipeGestureRecognizer) -> Bool {
if gesture.direction == .down {
// check if we have some values in down if yes return true else false
} else if gesture.direction == .up {
// check if we have some values in up if yes return true else false
}
return false
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.panGesture && otherGestureRecognizer == self.scrollGesture && isItemAvailabe(gesture: otherGestureRecognizer) {
return true
}
return false
}
如果这解决了您的问题或者我没有正确理解,请告诉我。
还记得加上这个:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
您可以查看更多here
最好的方法是使用 tableView 自己的 panGestureRecognizer(不添加新的 gestureRecognizer),例如:
tableView.panGestureRecognizer.addTarget(self, action: #selector(self.tableViewDragged(gestureRecognizer:))
动作
@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {
guard tableView.contentOffset.y < 0 else { return }
if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {
let translation = gestureRecognizer.translation(in: self.view)
// if origin moved to map origin it should not scroll above but cell should scroll normally. But returning does not help scrolling cells
if self.tableView.frame.origin == self.mapContainer.frame.origin && translation.y < 0 {
return
}
var frame = self.tableView.frame
let nHeight = (frame.origin.y + translation.y)
if (nHeight < self.view.frame.size.height) {
frame.origin.y = nHeight
self.tableView.frame = frame
gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
}
}
}