[英]Material Ripple Effect for UICollectionView Cell
I am trying to create a material ripple effect for a UICollectioView cell. 我正在尝试为UICollectioView单元创建材质波纹效果。 For Android, there are several material design options to do so, but for iOS that does not appear to be the case.
对于Android,可以使用多种材料设计选项,但对于iOS似乎并非如此。 Below is my custom cell I am using as the prototype to populate the UICollectioView:
以下是我用作模板填充UICollectioView的自定义单元格:
import UIKit
class PollCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var pollQuestion: UILabel!
}
Where I initialize the CollectioViewCell: 我在哪里初始化CollectioViewCell:
override func viewDidLoad() {
super.viewDidLoad()
ref = FIRDatabase.database().reference()
prepareMenuButton()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Register cell classes
self.dataSource = self.collectionView?.bind(to: self.ref.child("Polls")) { collectionView, indexPath, snap in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! PollCell
//Here is where I am having issues
cell.pulseAnimation
/* populate cell */
cell.pollQuestion.text = snap.childSnapshot(forPath: "question").value as! String?
let urlPollImage = snap.childSnapshot(forPath: "image_URL").value as! String?
cell.imageView.sd_setImage(with: URL(string: urlPollImage!), placeholderImage: UIImage(named: "Fan_Polls_Logo.png"))
//Comment
return cell
}
Here is an image of one of the cells on a device: 这是设备上一个单元的图像:
Use a CATransition 使用CATransition
func ripple(view:UIView){
let ripple = CATransition()
ripple.type = "rippleEffect"
ripple.duration = 0.5
view.layer.add(ripple, forKey: nil)
}
you can pass whatever you want to ripple and it will. 您可以传递任何您想要波动的东西,它会。 Example
例
self.ripple(view: imageView)
or you could pass the cell itself on didselect,touches began or whatever you are using to trigger the ripple. 或者您可以通过单元格本身进行didselect操作,触摸开始或您用来触发纹波的任何方法。
But based on what you are telling me you want a circular pulse to cover the view so I tried this. 但是根据您告诉我的内容,您想要一个圆形脉冲来覆盖视图,因此我尝试了此操作。 I put some libraries to consider in the comments but here is my quick attempt at what you are wanting.
我在评论中加入了一些库,但在这里您可以快速尝试一下。
var scaleFactor : CGFloat = 0.6
var animationColor : UIColor = UIColor.green
var animationDuration : Double = 0.4
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {.
super.touchesBegan(touches, with: event)
let coverView = UIView(frame: bounds)
coverView.autoresizingMask = [.flexibleWidth,.flexibleHeight]
coverView.backgroundColor = UIColor.clear
self.addSubview(coverView)
let touch = touches.first!
let point = touch.location(in: self)
let ourTouchView = UIView(frame: CGRect(x: point.x - 5, y: point.y - 5, width: 10, height: 10))
print(ourTouchView)
print(point)
let circleMaskPathInitial = UIBezierPath(ovalIn: ourTouchView.frame)
let radius = max((self.bounds.width * scaleFactor) , (self.bounds.height * scaleFactor))
let circleMaskPathFinal = UIBezierPath(ovalIn: ourTouchView.frame.insetBy(dx: -radius, dy: -radius))
let rippleLayer = CAShapeLayer()
rippleLayer.opacity = 0.4
rippleLayer.fillColor = animationColor.cgColor
rippleLayer.path = circleMaskPathFinal.cgPath
coverView.layer.addSublayer(rippleLayer)
//fade up
let fadeUp = CABasicAnimation(keyPath: "opacity")
fadeUp.beginTime = CACurrentMediaTime()
fadeUp.duration = animationDuration * 0.6
fadeUp.toValue = 0.6
fadeUp.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
fadeUp.fillMode = kCAFillModeForwards
fadeUp.isRemovedOnCompletion = false
rippleLayer.add(fadeUp, forKey: nil)
//fade down
let fade = CABasicAnimation(keyPath: "opacity")
fade.beginTime = CACurrentMediaTime() + animationDuration * 0.60
fade.duration = animationDuration * 0.40
fade.toValue = 0
fade.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
fade.fillMode = kCAFillModeForwards
fade.isRemovedOnCompletion = false
rippleLayer.add(fade, forKey: nil)
//change path
CATransaction.begin()
let maskLayerAnimation = CABasicAnimation(keyPath: "path")
maskLayerAnimation.fromValue = circleMaskPathInitial.cgPath
maskLayerAnimation.toValue = circleMaskPathFinal.cgPath
maskLayerAnimation.beginTime = CACurrentMediaTime()
maskLayerAnimation.duration = animationDuration
maskLayerAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
CATransaction.setCompletionBlock({
coverView.removeFromSuperview()
})
rippleLayer.add(maskLayerAnimation, forKey: "path")
CATransaction.commit()
}
I probably would not execute this in touches began and instead use a tap gesture but you could do this. 我可能不会在开始触摸时执行此操作,而是使用轻击手势,但是您可以执行此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.