UIView 动画在 iOS 8 中不能正常工作?

Posted

技术标签:

【中文标题】UIView 动画在 iOS 8 中不能正常工作?【英文标题】:UIView animation is not work properly in iOS 8? 【发布时间】:2018-02-17 12:33:39 【问题描述】:

我想创建如下动画,我是在 ios 11.2 中完成的。

我在 iOS 8.4 和 9.2 中对此进行了测试 - broke

故事板

我使用了 autoLaout

圆形阴影按钮

我继承了 UIButton。向其中添加了 RoundedCorner 和 DropShadow 协议。它包含一个处理动画的 animateButton 函数。

class RoundedShadowButton: UIButton, RoundedCorner, DropShadow 
    var originalSize: CGRect?

    func animateButton(shouldLoad: Bool, withMessage message: String?) 
        let spinner = UIActivityIndicatorView()
        spinner.activityIndicatorViewStyle = .whiteLarge
        spinner.color = .darkGray
        spinner.alpha = 0.0
        spinner.hidesWhenStopped = true
        spinner.tag = 21

        if shouldLoad 
            self.addSubview(spinner)
            self.setTitle("", for: .normal)
            UIView.animate(withDuration: 0.2, animations: 
                self.setRoundedCorners(radius: self.frame.height / 2)
                self.frame = CGRect(x: self.frame.midX - (self.frame.height / 2), y: self.frame.origin.y, width: self.frame.height, height: self.frame.height)
            , completion:  (finished) in
                if finished 
                    spinner.startAnimating()
                    spinner.center = CGPoint(x: self.frame.width / 2 + 1, y: self.frame.width / 2 + 1)
                    spinner.fadeTo(alphaValue: 1.0, withDuration: 0.2)
                
            )
            self.isUserInteractionEnabled = false
         else 
            self.isUserInteractionEnabled = true

            // remove spinner
            for subView in self.subviews 
                if subView.tag == 21 
                    subView.removeFromSuperview()
                
            

            // return back to original button
            UIView.animate(withDuration: 0.2, animations: 
                if let size = self.originalSize 
                    self.setRoundedCorners(radius: 8)
                    self.frame = size
                    self.setTitle(message, for: .normal)
                
            )
        
    

圆角

protocol RoundedCorner 

extension RoundedCorner where Self: UIView 
    func setRoundedCorners(radius: CGFloat) 
        layer.cornerRadius = radius
    

DropShadow

protocol DropShadow 

extension DropShadow where Self: UIView 
    func setShadow(width: CGFloat = 0, height: CGFloat = 0, opacity: Float, radius: CGFloat, color: UIColor) 
        layer.shadowColor = color.cgColor
        layer.shadowOpacity = opacity
        layer.shadowOffset = CGSize(width: width, height: height)
        layer.shadowRadius = radius
    

HomeVC

在 HomeVC 的 viewDidAppear 中,我设置了圆角半径、阴影和边框大小。在按钮 IBAction 中,我调用了 animate 函数。

override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        actionBtn.originalSize = actionBtn.frame
        actionBtn.setRoundedCorners(radius: 8)
        actionBtn.setShadow(opacity: 0.3, radius: 10.0, color: .darkGray)
    

@IBAction func actionBtnTapped(_ sender: Any) 
        self.actionBtn.animateButton(shouldLoad: true, withMessage: nil)
    

如何解决?

【问题讨论】:

您的前导/尾随约束很可能会阻止它调整大小。虽然它有效,但它不是你可以依赖的东西。使用约束时,您还需要使用约束来调整项目的大小。 @Sh_Khan 无效 @LGP 我将优先级更改为 999,但没有帮助。你身边的任何想法 在下面查看我的解决方案。 只需检查它没有约束并手动处理(意味着删除所有约束)。它会工作 【参考方案1】:

使用约束制作动画时,您还需要使用约束。尽管有时它可能会起作用,但它不是您可以依赖的东西。你可以这样解决。

删除leadingtrailing 约束。 将same width 添加为superview 减去40 的宽度约束。将其连接到名为 widthConstraintNSLayoutConstraint 类型的类变量。设置优先级750。 添加另一个宽度约束,将width 设置为与高度相同,使其变为圆形。将优先级设置为500。 在superview 内为center 添加约束。

现在,在您的代码中替换框架修改部分。

            self.frame = CGRect(x: self.frame.midX - (self.frame.height / 2), y: self.frame.origin.y, width: self.frame.height, height: self.frame.height)

有了这个。通过更改优先级,您可以选择应该生效的约束。由于宽约束在 750 处,它将胜过窄约束。将优先级更改为 250 时,窄约束获胜。

            self.widthConstraint.priority = 250
            self.layoutIfNeeded()

【讨论】:

我在哪里创建宽度约束?我在情节提要中创建了它,但是如何更改它的常量值?因为 RoundedShadowButton 类中的动画功能 是的,像 Storyboard 中的任何其他约束一样创建它。如果你双击约束,你会得到一个属性页,在那里你可以将它连接到你的变量。 但是 HomeVC 中的变量,如何在 RoundedShadowButton 类中访问它 将其作为参数传递给animateButton 或(或许更好)将其设置为RoundedShadowButton 对象的弱属性。 展开?不知道怎么会发生。您是否删除了按钮的前导/尾随约束?【参考方案2】:

在我的最后尝试它的工作,只需禁用它:

   self.view.translatesAutoresizingMaskIntoConstraints  = false

【讨论】:

以上是关于UIView 动画在 iOS 8 中不能正常工作?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 8 - 动画显示导航和状态栏无法正常工作

具有原点的动画 UIView 无法正常工作

UIView 动画无法正常工作?

UIView 动画在 UITableViewCell 内无法正常工作

IOS 8 高度约束动画未按预期工作

UIView 动画无法正常工作