使用 SnapKit 时无法正确设置动画

Posted

技术标签:

【中文标题】使用 SnapKit 时无法正确设置动画【英文标题】:Cannot animate properly when using SnapKit 【发布时间】:2019-03-05 16:26:18 【问题描述】:

我正在尝试为我的应用制作一个徽标 (UILabel) 的动画,从中间到顶部。我尝试的是更新约束,但它似乎不起作用。问题是动画,即徽标,从原点 (0,0) 而不是视图的中间到顶部。必要的代码(控制器及其继承的类):

import UIKit
import SnapKit

class EntryController: LatroController 

    static let spacingFromTheTop: CGFloat = 150
    var latroLabelCenterYConstraint: Constraint?

    override init() 
        super.init()
        self.animateTitleLabel()
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
    

    override func initTitleLabel() 
        self.latroLabel = UILabel()
        self.latroLabel?.text = General.latro.rawValue
        self.latroLabel?.textAlignment = .center
        self.latroLabel?.font = UIFont (name: General.latroFont.rawValue, size: EntryController.fontSize)
        self.latroLabel?.textColor = .white
        self.latroLabel?.contentMode = .center
        self.view.addSubview(self.latroLabel!)

        self.latroLabel?.snp.makeConstraints( (make) in
            make.width.equalTo(EntryController.latroWidth)
            make.height.equalTo(EntryController.latroHeight)
            make.centerX.equalTo(self.view.center.x)
            self.latroLabelCenterYConstraint = make.centerY.equalTo(self.view.center.y).constraint
        )
    

    func animateTitleLabel() 
        UIView.animate(withDuration: 1.5) 
            self.latroLabel?.snp.updateConstraints  (make) in
                make.centerY.equalTo(200)
            
            self.view.layoutIfNeeded()
        
    


import UIKit
import SnapKit

class LatroController: UIViewController 

static let latroWidth: CGFloat = 288
static let latroHeight: CGFloat = 98
static let btnWidth: CGFloat = 288
static let btnHeight: CGFloat = 70
static let txtFieldWidth: CGFloat = 288
static let txtFieldHeight: CGFloat = 50
static let fontSize: CGFloat = 70
static let bottomOffset: CGFloat = 100
static let buttonOffset: CGFloat = 20
static let logoOffset: CGFloat = 50

var latroLabel: UILabel?
var signUpBtn: UIButton?
var logInBtn: UIButton?
var titleLabelYConstraint: NSLayoutConstraint?
var usernameTxtField: UITextField?

init() 
    super.init(nibName: nil, bundle: nil)
    self.view.backgroundColor = UIColor(named: General.orange.rawValue)
    self.initTitleLabel()


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)


override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)
    self.navigationController?.setNavigationBarHidden(true, animated: false)


override func viewDidDisappear(_ animated: Bool) 
    super.viewDidDisappear(animated)
    self.navigationController?.setNavigationBarHidden(false, animated: true)


func initTitleLabel() 
    self.latroLabel = UILabel()
    self.latroLabel?.text = General.latro.rawValue
    self.latroLabel?.textAlignment = .center
    self.latroLabel?.font = UIFont (name: General.latroFont.rawValue, size: EntryController.fontSize)
    self.latroLabel?.textColor = .white
    self.latroLabel?.contentMode = .center
    self.view.addSubview(self.latroLabel!)

    self.latroLabel?.snp.makeConstraints( (make) in
        make.width.equalTo(LatroController.latroWidth)
        make.height.equalTo(LatroController.latroHeight)
        let safeAreaLayoutHeight = self.view.safeAreaLayoutGuide.layoutFrame.height
        print(safeAreaLayoutHeight)
        make.top.equalTo(self.view).offset(150)
        make.centerX.equalTo(self.view.center.x)
    )


【问题讨论】:

【参考方案1】:

在视图位于界面中并且执行初始布局之前,您无法为视图设置动画。因此,您调用self.animateTitleLabel() 太快了(在init 中)。

viewDidAppear 之类的形式调用它。当然,您必须使用 Bool 标志属性来确保您不会在 每次 viewDidAppear 运行时调用它,而只在 第一次 时调用它。

(可能需要改为在 viewDidLayoutSubviews 中调用它;您必须进行试验。)

【讨论】:

【参考方案2】:

好的,我认为这会比我最初预期的要难。缺少以下内容:

self.view.updateLayoutIfNeeded() 

设置约束后!

【讨论】:

聪明,但你不应该在不需要的时候强制进行一轮布局。正确的做法是“等待”布局自然发生。

以上是关于使用 SnapKit 时无法正确设置动画的主要内容,如果未能解决你的问题,请参考以下文章

UIButton 中的标题标签文本颜色无法正确设置动画

为啥我的 CAShapeLayer 无法使用 UIView(带 gif)正确设置动画?

更新模型层时,CABasicAnimation 无法正确设置动画

如何通过 swift 3 的 snapkit 向任何 UI 添加动画?

Recycler View 中的约束设置动画未正确设置动画

无法使用 Swift 为 UILabel 设置动画