Material UICollectionView 单元格的涟漪效应
Material Ripple Effect for UICollectionView Cell
我正在尝试为 UICollectioView 单元格创建 material 波纹效果。对于 Android,有几个 material 设计选项可以做到这一点,但对于 iOS 似乎并非如此。下面是我用作原型来填充 UICollectioView 的自定义单元格:
import UIKit
class PollCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var pollQuestion: UILabel!
}
我在哪里初始化 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
}
这是设备上其中一个单元格的图像:
使用 CATransition
func ripple(view:UIView){
let ripple = CATransition()
ripple.type = "rippleEffect"
ripple.duration = 0.5
view.layer.add(ripple, forKey: nil)
}
你可以通过任何你想要涟漪的东西,它会。例子
self.ripple(view: imageView)
或者您可以将单元格本身传递给 didselect、touches begin 或您用来触发涟漪的任何内容。
但是根据你告诉我的内容,你想要一个圆形脉冲来覆盖视图,所以我尝试了这个。我在评论中放了一些图书馆供考虑,但这是我对你想要的东西的快速尝试。
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()
}
我可能不会在触摸开始时执行此操作,而是使用点击手势,但你可以这样做。
如果你使用 Material 它有一个 CollectionViewCell
内置了脉冲动画。你可以用 pulseAnimation
属性 设置它。希望这可以帮助。
我正在尝试为 UICollectioView 单元格创建 material 波纹效果。对于 Android,有几个 material 设计选项可以做到这一点,但对于 iOS 似乎并非如此。下面是我用作原型来填充 UICollectioView 的自定义单元格:
import UIKit
class PollCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var pollQuestion: UILabel!
}
我在哪里初始化 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
}
这是设备上其中一个单元格的图像:
使用 CATransition
func ripple(view:UIView){
let ripple = CATransition()
ripple.type = "rippleEffect"
ripple.duration = 0.5
view.layer.add(ripple, forKey: nil)
}
你可以通过任何你想要涟漪的东西,它会。例子
self.ripple(view: imageView)
或者您可以将单元格本身传递给 didselect、touches begin 或您用来触发涟漪的任何内容。
但是根据你告诉我的内容,你想要一个圆形脉冲来覆盖视图,所以我尝试了这个。我在评论中放了一些图书馆供考虑,但这是我对你想要的东西的快速尝试。
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()
}
我可能不会在触摸开始时执行此操作,而是使用点击手势,但你可以这样做。
如果你使用 Material 它有一个 CollectionViewCell
内置了脉冲动画。你可以用 pulseAnimation
属性 设置它。希望这可以帮助。