UISwipeGestureRecognizer 和 CollectionView 滚动到下一个项目 indexPath
Posted
技术标签:
【中文标题】UISwipeGestureRecognizer 和 CollectionView 滚动到下一个项目 indexPath【英文标题】:UISwipeGestureRecognizer and CollectionView scroll to next item indexPath 【发布时间】:2017-02-15 10:34:21 【问题描述】:所以我有一个卡片的集合视图,我想要的是当我向左滑动时,我希望下一个项目居中,this doesn't work with paging enabled
所以当我向左滑动时,我希望下一张卡片居中,这不适用于正常行为,因为我只想刷一张卡片。
所以我添加了UISwipeGestureRecognizer
和disabled scrolling on the collection view
类 ViewController: UIViewController,UICollectionViewDataSource
@IBOutlet var joke_cards: UICollectionView!
override func viewDidLoad()
super.viewDidLoad();
//Add gestures
let leftSwipeGest = UISwipeGestureRecognizer(target: self, action: #selector(funcForGesture))
leftSwipeGest.direction = .left
joke_cards.addGestureRecognizer(leftSwipeGest)
func funcForGesture(sender: UISwipeGestureRecognizer)
if sender.direction == .left
//scroll to next item
现在我的问题是如何滚动到下一个项目?因为我不知道 indexPath?因为如果我想使用这个self.joke_cards.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
,我需要索引路径,所以我想我需要弄清楚视图上的当前indexPath和用户滑动时的add one
。
有什么建议吗?
//更新 所以我设法让它工作,但它只在我第一次刷卡时有效:
func funcForGesture(sender: UISwipeGestureRecognizer)
if sender.direction == .left
//scroll to next item
let cellItems = self.joke_cards.indexPathsForVisibleItems
let next = cellItems[0] as! IndexPath
self.joke_cards.scrollToItem(at: next, at: .centeredHorizontally, animated: true)
【问题讨论】:
你的卡是什么?一个collectionview单元或?? 是的,每张卡片都是一个collectionview单元 所以你可以根据你的数组值使用 self.joke_cards.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true) 按照以下答案中的第一个解决方案 【参考方案1】:一种解决方案:
1:将NSIndexPath
属性添加到您的单元格中,并在您的cellForItem
方法中将indexPath 设置为该属性。
2:获取array of visible cells.
3:Get the rect of the visible 单元格并计算它们在屏幕上的位置,您还可以从单元格属性中获取正确的 indexPath。
第二种解决方案:
1:在单元格内容视图中添加UILongPressGestureRecognizer
2:将minimumPressDuration 设置为 0。
3:添加委托方法来触发 acitons or this.
第三种解决方案:
1:保持滑动手势。
2:And use this method(与选项 2 相同)indexPathForItemAtPoint:
【讨论】:
我让它工作,检查我更新的帖子,但它只适用于第一次滑动,我做错了什么?谢谢! @Uffo 我很高兴它成功了。我不知道什么不适合你?刷卡方法是否会触发?我想也许你应该在触发动作之前处理不同的状态手势:developer.apple.com/reference/uikit/uigesturerecognizerstate/…,这只是开始,你应该按照你认为合适的方式正确处理它们。 是的,它有效,它滑动但只有第一次,第二次没有做任何事情,方法触发,我放了一条调试消息,我认为是因为 let next = cellItems[0 ] 作为! IndexPath 我觉得每次都需要更新索引键,不知道怎么更新,第二次应该是[cellItems][1] @Uffo 收到数组中的单元格时使用此方法获取indexPath: let indexPath = self.collectionView.indexPath(for: cell) ,注意可以查看多个单元格的indexPaths只需比较它们,看看哪一个是“最高”的 indexPath.item 或“最低”,具体取决于您要向右或向左滑动。因为您将始终获得 3 个根据您的图像可见的项目。您也可以尝试数组的“lastItem”或“firstItem”,看看哪种最适合您 你把我弄糊涂了,它不是这样工作的: func funcForGesture(sender: UISwipeGestureRecognizer) if sender.direction == .left //滚动到下一项 let cellItems = self.joke_cards .indexPathsForVisibleItems 让 indexPath = self.joke_cards.indexPath(for: cellItems) self.joke_cards.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true) 【参考方案2】:为什么你说这在启用分页时不起作用?在我看来,这实际上应该是最好的方法。您可以使UICollectionViewCells
的宽度等于UICollectionView
的宽度,将滚动方向设置为水平并启用分页,这应该可以解决问题。
这样你就不需要UIGestureRecognizers
了。
【讨论】:
它工作得很好......但它可以一次滚动多个项目,我不想要那个 不应该这样。分页背后的整个想法是一次只滚动一个视图。我已经多次使用它并且它有效。这甚至是苹果提供的定义:“UIScrollView 类支持分页模式,该模式将用户发起的滚动操作限制为一次滚动单个屏幕的内容。当显示顺序内容时使用此模式,例如电子书或一系列指令。”【参考方案3】:好的,所以解决方案是这样的:
@IBOutlet var joke_cards: UICollectionView!
override func viewDidLoad()
super.viewDidLoad();
//Add gestures
let leftSwipeGest = UISwipeGestureRecognizer(target: self, action: #selector(funcForGesture))
leftSwipeGest.direction = .left
joke_cards.addGestureRecognizer(leftSwipeGest)
func funcForGesture(sender: UISwipeGestureRecognizer)
if sender.direction == .left
//scroll to next item
let cellItems = self.joke_cards.indexPathsForVisibleItems
self.joke_cards.scrollToItem(at: cellItems.max()!, at: .centeredHorizontally, animated: true)
【讨论】:
以上是关于UISwipeGestureRecognizer 和 CollectionView 滚动到下一个项目 indexPath的主要内容,如果未能解决你的问题,请参考以下文章
识别用户剪切/滑动手势 (UISwipeGestureRecognizer)
UISwipeGestureRecognizer 只有一个方向工作
如何检测 UISwipeGestureRecognizer 的结束?