iOS - 水平滑动 UICollectionViewCell
iOS - swipe UICollectionViewCell horizontally
我有一个看起来像 tableView 的 UICollectionView,我希望单元格只能水平滑动。
我设法让它们四处移动,但问题是我也可以将它们向上移动,基本上我可以向任何方向移动它们,我希望它们在删除时像 tableViewCell 一样滑动,例如.
最后我希望能够将一个单元格水平滑出屏幕
我附上了一张集合视图现在的样子的图片和一个四处移动的单元格(红色的)
您需要做几件事:
1) 在每个单元格中添加一个 UISwipeGestureRecognizer
。请务必设置 direction = .left
。
2) 为手势识别器添加目标,并确保目标可以与 collection 视图的布局通信。 2a) collection 视图数据源可以在 cellForItemAtIndexPath
中添加目标。您需要一种方法来确保它不会重复添加到重复使用的单元格上。 2b) 您可以从单元格中添加手势识别器,并与您的视图控制器创建委托关系。
3) 您将需要被滑动的单元格的索引路径。要从手势识别器 (2a) 获取单元格,请调用它 view
属性 并将其转换为 UICollectionViewCell。如果您使用委托 (2b) 或其他方法,它应该将单元格传回。然后你可以调用 collectionView.cellForItem(at indexPath: IndexPath) -> UICollectionViewCell?
来获取索引路径。
4) 在 collection 视图中调用 deleteItemAtIndexPath:
,在 performBatchUpdates
等
5) 似乎最简单的方法是为左侧的消失设置动画(免责声明,虽然我使用过属性,但我自己还没有完成这部分)是在的子类中实现 finalLayoutAttributesForDisappearingItemAtIndexPath: UICollectionViewLayout。
首先,您需要缓存属性。所以覆盖并缓存:
class LeftDisappearLayout : UICollectionViewFLowLayout {
var cachedAttributes = [NSIndexPath:UICollectionViewAttributes?]()
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = super.layoutAttributesForItem(at: indexPath)
cachedAttributes[indexPath] = attributes
return attributes
}
然后从 iOS 9 开始,似乎有一种简单的方法可以让系统为您向左动画:
func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
if var attributes = cachedAttributes[indexPath] {
let newCenterX : CGFloat = -1 * (attributes.frame.size.width / 2)
attributes.center = CGPoint(newCenterX, attributes.center.y)
return attributes
}
AssertionFailure("Unable to find cached attributes!") // Saying, "This should never happen and in development crash to alert the developer, but in production gracefully revert to default."
return nil
}
}
确保将您的 collection 视图设置为使用此布局。希望这有帮助。
我终于找到了用 UIPanGestureRecognizer
做的方法。所有操作都在单元格上(在单元格 class 内)。下面是对我有用的解决方案
var swipeGesture: UIPanGestureRecognizer!
var originalPoint: CGPoint!
func configureCell() {
setupSwipeGesture()
}
func setupSwipeGesture() {
swipeGesture = UIPanGestureRecognizer(target: self, action:#selector(swiped(_:)))
swipeGesture.delegate = self
self.addGestureRecognizer(swipeGesture)
}
func swiped(_ gestureRecognizer: UIPanGestureRecognizer) {
let xDistance:CGFloat = gestureRecognizer.translation(in: self).x
switch(gestureRecognizer.state) {
case UIGestureRecognizerState.began:
self.originalPoint = self.center
case UIGestureRecognizerState.changed:
let translation: CGPoint = gestureRecognizer.translation(in: self)
let displacement: CGPoint = CGPoint.init(x: translation.x, y: translation.y)
if displacement.x + self.originalPoint.x < self.originalPoint.x {
self.transform = CGAffineTransform.init(translationX: displacement.x, y: 0)
self.center = CGPoint(x: self.originalPoint.x + xDistance, y: self.originalPoint.y)
}
case UIGestureRecognizerState.ended:
let hasMovedToFarLeft = self.frame.maxX < UIScreen.main.bounds.width / 2
if (hasMovedToFarLeft) {
removeViewFromParentWithAnimation()
} else {
resetViewPositionAndTransformations()
}
default:
break
}
}
func resetViewPositionAndTransformations(){
UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.0, options: UIViewAnimationOptions(), animations: {
self.center = self.originalPoint
self.transform = CGAffineTransform(rotationAngle: 0)
}, completion: {success in })
}
func removeViewFromParentWithAnimation() {
var animations:(()->Void)!
animations = {self.center.x = -self.frame.width}
UIView.animate(withDuration: 0.2, animations: animations , completion: {success in self.removeFromSuperview()})
}
我有一个看起来像 tableView 的 UICollectionView,我希望单元格只能水平滑动。
我设法让它们四处移动,但问题是我也可以将它们向上移动,基本上我可以向任何方向移动它们,我希望它们在删除时像 tableViewCell 一样滑动,例如.
最后我希望能够将一个单元格水平滑出屏幕
我附上了一张集合视图现在的样子的图片和一个四处移动的单元格(红色的)
您需要做几件事:
1) 在每个单元格中添加一个 UISwipeGestureRecognizer
。请务必设置 direction = .left
。
2) 为手势识别器添加目标,并确保目标可以与 collection 视图的布局通信。 2a) collection 视图数据源可以在 cellForItemAtIndexPath
中添加目标。您需要一种方法来确保它不会重复添加到重复使用的单元格上。 2b) 您可以从单元格中添加手势识别器,并与您的视图控制器创建委托关系。
3) 您将需要被滑动的单元格的索引路径。要从手势识别器 (2a) 获取单元格,请调用它 view
属性 并将其转换为 UICollectionViewCell。如果您使用委托 (2b) 或其他方法,它应该将单元格传回。然后你可以调用 collectionView.cellForItem(at indexPath: IndexPath) -> UICollectionViewCell?
来获取索引路径。
4) 在 collection 视图中调用 deleteItemAtIndexPath:
,在 performBatchUpdates
等
5) 似乎最简单的方法是为左侧的消失设置动画(免责声明,虽然我使用过属性,但我自己还没有完成这部分)是在的子类中实现 finalLayoutAttributesForDisappearingItemAtIndexPath: UICollectionViewLayout。
首先,您需要缓存属性。所以覆盖并缓存:
class LeftDisappearLayout : UICollectionViewFLowLayout {
var cachedAttributes = [NSIndexPath:UICollectionViewAttributes?]()
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = super.layoutAttributesForItem(at: indexPath)
cachedAttributes[indexPath] = attributes
return attributes
}
然后从 iOS 9 开始,似乎有一种简单的方法可以让系统为您向左动画:
func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
if var attributes = cachedAttributes[indexPath] {
let newCenterX : CGFloat = -1 * (attributes.frame.size.width / 2)
attributes.center = CGPoint(newCenterX, attributes.center.y)
return attributes
}
AssertionFailure("Unable to find cached attributes!") // Saying, "This should never happen and in development crash to alert the developer, but in production gracefully revert to default."
return nil
}
}
确保将您的 collection 视图设置为使用此布局。希望这有帮助。
我终于找到了用 UIPanGestureRecognizer
做的方法。所有操作都在单元格上(在单元格 class 内)。下面是对我有用的解决方案
var swipeGesture: UIPanGestureRecognizer!
var originalPoint: CGPoint!
func configureCell() {
setupSwipeGesture()
}
func setupSwipeGesture() {
swipeGesture = UIPanGestureRecognizer(target: self, action:#selector(swiped(_:)))
swipeGesture.delegate = self
self.addGestureRecognizer(swipeGesture)
}
func swiped(_ gestureRecognizer: UIPanGestureRecognizer) {
let xDistance:CGFloat = gestureRecognizer.translation(in: self).x
switch(gestureRecognizer.state) {
case UIGestureRecognizerState.began:
self.originalPoint = self.center
case UIGestureRecognizerState.changed:
let translation: CGPoint = gestureRecognizer.translation(in: self)
let displacement: CGPoint = CGPoint.init(x: translation.x, y: translation.y)
if displacement.x + self.originalPoint.x < self.originalPoint.x {
self.transform = CGAffineTransform.init(translationX: displacement.x, y: 0)
self.center = CGPoint(x: self.originalPoint.x + xDistance, y: self.originalPoint.y)
}
case UIGestureRecognizerState.ended:
let hasMovedToFarLeft = self.frame.maxX < UIScreen.main.bounds.width / 2
if (hasMovedToFarLeft) {
removeViewFromParentWithAnimation()
} else {
resetViewPositionAndTransformations()
}
default:
break
}
}
func resetViewPositionAndTransformations(){
UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.0, options: UIViewAnimationOptions(), animations: {
self.center = self.originalPoint
self.transform = CGAffineTransform(rotationAngle: 0)
}, completion: {success in })
}
func removeViewFromParentWithAnimation() {
var animations:(()->Void)!
animations = {self.center.x = -self.frame.width}
UIView.animate(withDuration: 0.2, animations: animations , completion: {success in self.removeFromSuperview()})
}