在 swift iOS 中为 3 个点设置动画
Posted
技术标签:
【中文标题】在 swift iOS 中为 3 个点设置动画【英文标题】:Animating 3 dots in swift iOS 【发布时间】:2021-09-03 14:23:20 【问题描述】:我有一个标签和一个图像视图。我的目标是在标签的前面有 3 个点动画,并在最后的标签脚下,如此处所示
我已经能够使这个设计在 12promax 上移动得很好,但是我无法弄清楚如何让这个设计始终在不同的手机屏幕尺寸上按预期工作。怎么编码,不管屏幕大小还是 uilabel fontsize 都能达到一样的效果?
动画 ImageView(3 个点)
func showAnimatingDotsInImageView(dots: UIImageView)
let newX = view.bounds.width / 896 * 20
let lay = CAReplicatorLayer()
lay.frame = CGRect(x: newX,y: 0,width: dots.bounds.width,height: dots.bounds.height)
let bar = CALayer()
bar.frame = CGRect(x: 0,y: (dots.bounds.height/2) + 8 ,width: 8,height: 8) //make the objs smaller or bigger
bar.cornerRadius = bar.frame.width / 2 //make a circle, if you uncomment this you will get rects
bar.backgroundColor = UIColor.black.cgColor //colour of the objs
lay.addSublayer(bar)
lay.instanceCount = 3 //How many instances / objs do you want to see
lay.instanceTransform = CATransform3DMakeTranslation(15, 0, 0) //1st arg is the spacing between the instances
let anim = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
anim.fromValue = 1.0
anim.toValue = 0.2
anim.duration = 1
anim.repeatCount = .infinity
bar.add(anim, forKey: nil)
lay.instanceDelay = anim.duration / Double(lay.instanceCount)
dots.layer.addSublayer(lay) // add to the view
“从主菜单中检索框”是 UILabel
,点在 UIImageView
上进行动画处理
【问题讨论】:
您的屏幕截图是否在标签的右边缘显示UILabel
和UIImageView
?
@DonMag 是的。 UIImage 在它的右边
【参考方案1】:
您已经很接近了...只需进行一些更改即可到达您想要的位置。
如果您有一个UILabel
和一个UIImageView
(或普通UIView
)被限制在标签的右边缘,您应该能够定位您的CAReplicatorLayer
,而不必担心“屏幕尺寸”。
看看我是如何修改你的代码的:
// baseline = to put the bottom of the dots at the baseline of the text in the label
// dotXOffset = gap between end of label and first dot
// dotSize = dot width and height
// dotSpacing = gap between dots
func showAnimatingDotsInImageView(dotsView: UIView, baseline: CGFloat, dotXOffset: CGFloat, dotSize: CGFloat, dotSpacing: CGFloat)
let lay = CAReplicatorLayer()
let bar = CALayer()
bar.frame = CGRect(x: dotXOffset, y: baseline - dotSize, width: dotSize, height: dotSize)
bar.cornerRadius = bar.frame.width / 2 // we want round dots
bar.backgroundColor = UIColor.black.cgColor
lay.addSublayer(bar)
lay.instanceCount = 3 //How many instances / objs do you want to see
lay.instanceTransform = CATransform3DMakeTranslation(dotSpacing, 0, 0) //1st arg is the spacing between the instances
let anim = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
anim.fromValue = 1.0
anim.toValue = 0.2
anim.duration = 1
anim.repeatCount = .infinity
bar.add(anim, forKey: nil)
lay.instanceDelay = anim.duration / Double(lay.instanceCount)
dotsView.layer.addSublayer(lay) // add to the view
这是一个完整的例子:
class SimpleViewController: UIViewController
let testLabel = UILabel()
let testDotsView = UIView()
override func viewDidLoad()
super.viewDidLoad()
testLabel.font = .systemFont(ofSize: 24.0)
testLabel.text = "Retrieving boxes"
// so we can see the label frame
testLabel.backgroundColor = .cyan
testLabel.translatesAutoresizingMaskIntoConstraints = false
testDotsView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(testLabel)
view.addSubview(testDotsView)
// always respect safe area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// let's constrain the label
// 40-pts from Leading
// 40-pts from Bottom
testLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
testLabel.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -40.0),
// constrain dots view to
// Top of label
// Trailing of label
testDotsView.topAnchor.constraint(equalTo: testLabel.topAnchor),
testDotsView.leadingAnchor.constraint(equalTo: testLabel.trailingAnchor, constant: 0.0),
// dots image view Width and Height can be 0 (we can draw the layer outside the bounds)
testDotsView.heightAnchor.constraint(equalToConstant: 0.0),
testDotsView.widthAnchor.constraint(equalToConstant: 0.0),
])
// get the label font's baseline y-value
let bl: CGFloat = testLabel.font.ascender
showAnimatingDotsInImageView(dotsView: testDotsView, baseline: bl, dotXOffset: 4.0, dotSize: 4.0, dotSpacing: 8.0)
// baseline = to put the bottom of the dots at the baseline of the text in the label
// dotXOffset = gap between end of label and first dot
// dotSize = dot width and height
// dotSpacing = gap between dots
func showAnimatingDotsInImageView(dotsView: UIView, baseline: CGFloat, dotXOffset: CGFloat, dotSize: CGFloat, dotSpacing: CGFloat)
let lay = CAReplicatorLayer()
let bar = CALayer()
bar.frame = CGRect(x: dotXOffset, y: baseline - dotSize, width: dotSize, height: dotSize)
bar.cornerRadius = bar.frame.width / 2 // we want round dots
bar.backgroundColor = UIColor.black.cgColor
lay.addSublayer(bar)
lay.instanceCount = 3 //How many instances / objs do you want to see
lay.instanceTransform = CATransform3DMakeTranslation(dotSpacing, 0, 0) //1st arg is the spacing between the instances
let anim = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
anim.fromValue = 1.0
anim.toValue = 0.2
anim.duration = 1
anim.repeatCount = .infinity
bar.add(anim, forKey: nil)
lay.instanceDelay = anim.duration / Double(lay.instanceCount)
dotsView.layer.addSublayer(lay) // add to the view
【讨论】:
感谢您的帮助和详细的代码cmets!我真的学到了很多以上是关于在 swift iOS 中为 3 个点设置动画的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中为选定的 UIPickerView 行设置动画背景颜色