欢迎访问宙启技术站
智能推送

仿iOS图标抖动

发布时间:2023-05-18 04:21:12

iOS设备中的应用图标可以抖动,通常是在编辑模式中长按一个应用图标,或者在某些情况下,如下载或安装应用程序时,应用程序图标也会抖动。这种抖动感觉非常有趣,也非常有用,因为它引起了用户的注意,并提示用户可以对图标进行某些操作。在下面的文章中,我们将介绍如何在应用程序中模仿iOS图标抖动效果。

1.添加长按手势

首先,我们需要添加一个长按手势(UILongPressGestureRecognizer),以便我们可以在用户长按应用程序图标时触发抖动效果。在视图控制器中添加以下代码:

let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))

override func viewDidLoad() {
    super.viewDidLoad()
    view.addGestureRecognizer(longPressRecognizer)
}

@objc func handleLongPress(_ sender: UILongPressGestureRecognizer) {
    if sender.state == .began {
        startShakingIcons()
    }
}

在ViewController类中声明手势,然后将其作为一个子视图添加到界面。当手势开始时,调用startShakingIcons()函数。

2.抖动动画

接下来,我们需要编写一个函数来控制应用程序图标的抖动动画。抖动动画是通过将图标旋转一定角度来实现的。在这里,我们需要创建一个UIView动画块,并在其中执行一旦应用程序图标被选择就运行动画的代码:

func startShakingIcons() {
    for item in (navigationController?.navigationBar.subviews)! {
        if let iconView = extractIconImageView(item) {
            let rotationDegrees: CGFloat = 0.5
            let repeatCount: Float = 8
            let animationDuration: TimeInterval = 0.5
            let leftWobble = CGAffineTransform(rotationAngle: degreesToRadians(rotationDegrees * -1.0))
            let rightWobble = CGAffineTransform(rotationAngle: degreesToRadians(rotationDegrees))
            
            iconView.transform = leftWobble
            UIView.animate(withDuration: animationDuration, delay: 0.0, options: [.repeat, .autoreverse], animations: {
                UIView.setAnimationRepeatCount(repeatCount)
                iconView.transform = rightWobble
            }) { (finished) in
                iconView.transform = .identity
            }
        }
    }
}

func extractIconImageView(_ subview: UIView) -> UIImageView? {
    for item in subview.subviews {
        if let imageView = item as? UIImageView, String(describing: type(of: item)) == "UIImageView" {
            return imageView
        } else if let iconImageView = extractIconImageView(item) {
            return iconImageView
        }
    }
    return nil
}

func degreesToRadians(_ degrees: CGFloat) -> CGFloat {
    return degrees * .pi / 180
}

在这个函数中,我们首先枚举导航栏子视图的所有子视图,查找应用程序图标的UIImageView。接下来,我们创建了leftWobble和rightWobble转换,将应用程序图标在两者之间来回抖动。然后,我们将这些变换应用到图标视图的transform属性上,然后开始一个UIView动画块来改变其transform属性。

动画是通过动画选项 [.repeat, .autoreverse] 和临时改变imageView视图的transform属性来实现的,这会使视图在一定时间内来回抖动(repeatCount)。最后,我们在动画完成块中将图标视图的transform属性重置为身份变换,这可以使图标在抖动结束时完美停止。

3. 给抖动图标添加功能

当我们的应用程序图标抖动时,用户需要知道哪些图标可以进行其他操作。一种常见的方法是类似于“三角形,橙色徽章”,通过在图标顶部添加一个徽章或标记来识别。

我们可以改变抖动图标的样式来表明它们可以进行其他操作。例如,在我们的startShakingIcons()函数中,我们可以为将要抖动的图标视图添加一个边框和一个未读计数视图。这有助于用户识别它们可以进行某些操作,并且为下一步实现功能提供了基础。

func startShakingIcons() {
    for item in (navigationController?.navigationBar.subviews)! {
        if let iconView = extractIconImageView(item) {
            let rotationDegrees: CGFloat = 0.5
            let repeatCount: Float = 8
            let animationDuration: TimeInterval = 0.5
            let leftWobble = CGAffineTransform(rotationAngle: degreesToRadians(rotationDegrees * -1.0))
            let rightWobble = CGAffineTransform(rotationAngle: degreesToRadians(rotationDegrees))
            let unreadCountView = UIView(frame: CGRect(x: iconView.bounds.width / 2 + 8, y: 4, width: 16, height: 16))
            let contentView = UIView(frame: CGRect(x: 0, y: 0, width: 16, height: 16))
            let borderView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: iconView.bounds.width - 2, height: iconView.bounds.height - 2)))
            
            borderView.tag = 1001
            borderView.layer.borderWidth = 1.5
            borderView.layer.borderColor = UIColor.white.cgColor
            borderView.layer.cornerRadius = 10.0
            borderView.layer.masksToBounds = true
            
            unreadCountView.layer.cornerRadius = 8.0
            unreadCountView.layer.masksToBounds = true
            unreadCountView.backgroundColor = .orange
            
            contentView.addSubview(unreadCountView)
            contentView.backgroundColor = .clear
            contentView.tag = 1002
            
            iconView.addSubview(contentView)
            iconView.addSubview(borderView)
            
            iconView.transform = leftWobble
            UIView.animate(withDuration: animationDuration, delay: 0.0, options: [.repeat, .autoreverse], animations: {
                UIView.setAnimationRepeatCount(repeatCount)
                iconView.transform = rightWobble
            }) { (finished) in
                iconView.transform = .identity
                for view in iconView.subviews {
                    if view.tag == 1001 || view.tag == 1002 {
                        view.removeFromSuperview()
                    }
                }
            }
        }
    }
}

在这个函数中,我们为每个找到的应用程序图标添加了一个未读计数视图(unreadCountView),一个紫边框(borderView)和一个contentView。contentView包含unreadCountView和有边框的视图。这个抖动函数还将contentView和borderView添加到应用程序图标上。当抖动结束时,我们删除contentView和borderView,以便视图能够回到其初始状态。

以上是模仿iOS图标抖动效果的完整思路,可以通过将该效果实现到自己的app中,使app的功能更加齐全,有趣。