#ios #snapkit
#iOS #snapkit
Вопрос:
Я пытаюсь анимировать логотип (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 flag, чтобы убедиться, что вы вызываете его не прикаждом viewDidAppear
запуске, а только в первый раз.
(Вместо этого может потребоваться вызвать его viewDidLayoutSubviews
; вам придется поэкспериментировать.)
Ответ №2:
Ладно, подумал, что это будет сложнее, чем я изначально ожидал. Отсутствовало следующее:
self.view.updateLayoutIfNeeded()
после установки ограничений!
Комментарии:
1. Умно, но вы не должны форсировать верстку, когда в этом нет необходимости. Правильнее всего «подождать», пока макет произойдет естественным ходом вещей.