在 Swift 中高亮时使 CollectionViewCell 反弹
Posted
技术标签:
【中文标题】在 Swift 中高亮时使 CollectionViewCell 反弹【英文标题】:Make a CollectionViewCell bounce on highlight in Swift 【发布时间】:2016-02-06 01:31:29 【问题描述】:在过去的几个小时里,我尝试完成以下工作:
在 UICollectionview 中,当我突出显示(向下触摸)一个单元格时,我希望它向内反弹几个像素(到更小的尺寸)并在释放时反弹回原始尺寸。
这是我迄今为止尝试过的:
override func collectionView(collectionView: UICollectionView,
didHighlightItemAtIndexPath indexPath: NSIndexPath)
collectionView.collectionViewLayout.invalidateLayout()
let cell = collectionView.cellForItemAtIndexPath(indexPath)
UIView.transitionWithView(cell!, duration: 1, options: UIViewAnimationOptions.CurveEaseIn, animations:
let center = cell?.center
let frame2 = CGRect(x: 0, y: 0, width: 50, height: 50)
cell?.frame = frame2
cell?.center = center!
, completion: nil)
(我从这个问题中找到了很多这个代码示例: UICollectionView: Animate cell size change on selection 但这适用于单元格选择。不突出。 )
所以在 didHighlightItemAtIndexPath 中,我将突出显示的单元格设置为新大小。大小设置正确,但出现以下问题: 1:它没有动画, 2:它移动到位置 (0,0) 并动画回到中心位置。它根本不应该移动位置 - 只是大小。
我在 Shazam 应用中看到了这种效果,以供参考。当您在歌曲名称下方的按钮上对歌曲进行 shazam (或查看以前的 shazad 歌曲)时,可以看到它。
【问题讨论】:
【参考方案1】:在UICollectionViewCell
子类中,您可以使用以下代码。我建议不要使用touchesBegan
和touchesEnded
,因为覆盖它们会禁用UICollectionView
的didSelectItemAt
委托方法,因此您必须通过自己的委托单独处理。如果您在视图控制器中使用didSelectItemAt
委托方法,那么正确的动画方法是覆盖isHighlighted
属性。
斯威夫特 3/4-
override var isHighlighted: Bool
didSet
if isHighlighted
UIView.animate(withDuration: 0.2, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 1.0, options: .curveEaseOut, animations:
self.transform = self.transform.scaledBy(x: 0.75, y: 0.75)
, completion: nil)
else
UIView.animate(withDuration: 0.2, delay: 0.0, usingSpringWithDamping: 0.4, initialSpringVelocity: 1.0, options: .curveEaseOut, animations:
self.transform = CGAffineTransform.identity.scaledBy(x: 1.0, y: 1.0)
, completion: nil)
【讨论】:
执行此操作后,我无法在点击边缘附近时选择单元格。有什么建议吗?【参考方案2】:Swift 4一点点重构代码
override var isHighlighted: Bool
didSet bounce(isHighlighted)
func bounce(_ bounce: Bool)
UIView.animate(
withDuration: 0.8,
delay: 0,
usingSpringWithDamping: 0.4,
initialSpringVelocity: 0.8,
options: [.allowUserInteraction, .beginFromCurrentState],
animations: self.transform = bounce ? CGAffineTransform(scaleX: 0.9, y: 0.9) : .identity ,
completion: nil)
【讨论】:
【参考方案3】:这是一般要点,虽然它不能处理所有边缘情况。
class MyCollectionViewCell: UICollectionViewCell
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
UIView.animateWithDuration(0.5) () -> Void in
let shrinkTransform = CGAffineTransformScale(CGAffineTransformIdentity, 0.5, 0.5)
self.transform = shrinkTransform
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?)
super.touchesEnded(touches, withEvent: event)
UIView.animateWithDuration(0.5) () -> Void in
self.transform = CGAffineTransformIdentity
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource
let l = UICollectionViewFlowLayout()
var c: UICollectionView! = nil
override func viewDidLoad()
super.viewDidLoad()
l.itemSize = CGSize(width: 400, height: 44)
c = UICollectionView(frame: CGRectZero, collectionViewLayout: l)
c.delegate = self
c.dataSource = self
c.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: "cellID")
view.addSubview(c)
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
c.frame = view.bounds
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
return 1
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 100
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellID", forIndexPath: indexPath) as! MyCollectionViewCell
if cell.contentView.subviews.count == 0
let label = UILabel(frame: CGRectZero)
label.text = "Row: \(indexPath.row)"
cell.contentView.addSubview(label)
label.frame = cell.contentView.bounds
cell.contentView.backgroundColor = UIColor.whiteColor()
return cell
这是一个视频:http://cl.ly/1Z3n2S2j0K3t
对不起,糟糕的格式,妈妈打来电话,晚餐准备好了。
【讨论】:
多么棒的答案!刚刚看了视频,这正是我所追求的!如果我能让它工作,我会尝试实施它并接受答案:) 谢谢你的回答 - 希望晚餐很好!以上是关于在 Swift 中高亮时使 CollectionViewCell 反弹的主要内容,如果未能解决你的问题,请参考以下文章
Swift UI VStack 对齐。按下时使文本字段与键盘一起出现
通过 UIButton 选择一个单元格 - CollectionViewCell - Swift
使用动态tableView的tableViewCell中的动态collectionViewCell执行Segue With Identifier,swift