Анимация представления на viewDidAppear не работает правильно - Swift
Я пытаюсь получить view
для анимации из центра экрана, чтобы покинуть экран через 1 секунду при загрузке изображения.
У меня проблема в том, что после миллисекунды view
находясь в исходном (правильном) положении при загрузке, он затем привязывается к новой позиции и анимирует обратно в исходную позицию.
У меня есть следующий код в viewDidLoad
override func viewDidAppear(animated: Bool) {
UIView.animateWithDuration(0.7, delay: 1, options: .CurveEaseOut, animations: {
var loadingViewFrame = self.loadingView.frame
loadingViewFrame.origin.y += 600
self.loadingView.frame = loadingViewFrame
}, completion: { finished in
print("moved")
})
}
Я пытался поместить этот код в button
действие, и оно отлично работает, поэтому есть ли другой метод, который я должен использовать при анимации на viewWillAppear
или я что-то пропустил?
Я удалил все ограничения автоматического размещения, потому что я прочитал, что они могут вызвать некоторые проблемы.
У меня также есть другой код в viewDidAppear
так же как viewWillAppear
а также viewDidLoad
который я мог бы показать здесь, если вы считаете, что это полезно, но я закомментировал весь этот код, оставив только базовый код, и та же ошибка все еще происходит.
Большое спасибо за вашу помощь.
Редактировать 1
Я переместил код в viewDidLayoutSubviews
и использовали dispatch_once
чтобы убедиться, что это делается только один раз. Изображение все еще анимируется из новой позиции в исходную позицию, но теперь изображение не находится в исходной позиции в течение миллисекунды после загрузки.
Это код, который я добавил
var token: dispatch_once_t = 0
override func viewDidLayoutSubviews() {
dispatch_once(&token) {
UIView.animateWithDuration(0.7, delay: 1, options: .CurveEaseOut, animations: {
var loadingViewFrame = self.loadingView.frame
loadingViewFrame.origin.x += 600
self.loadingView.frame = loadingViewFrame
}, completion: { finished in
print("moved")
})
}
}
1 ответ
Прежде всего, вам нужно позвонить super.viewDidAppear(animated)
когда вы переопределите viewDidAppear:
по вашему мнению, подкласс контроллера.
К сожалению, мне кажется, что с этим контроллером представления у меня все в порядке, так что должно быть что-то еще...
class ViewController: UITableViewController {
var loadingView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
loadingView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
loadingView.backgroundColor = UIColor.redColor()
loadingView.center = view.center
view.addSubview(loadingView)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
UIView.animateWithDuration(0.7, delay: 1, options: .CurveEaseOut, animations: {
var loadingViewFrame = self.loadingView.frame
loadingViewFrame.origin.y += 600
self.loadingView.frame = loadingViewFrame
}, completion: nil)
}
}
Ваша проблема, скорее всего, потому что layoutSubviews
может быть вызван после viewDidAppear:
(Я полагаю, что это отличается для iOS 8 и iOS 9), поэтому сделанные вами изменения будут отменены практически сразу. Вы можете подтвердить это, переопределив viewDidLayoutSubviews
в вашем UIViewController
подкласс и точка останова viewDidLoad
, viewWillAppear:
, viewDidAppear:
, а также viewDidLayoutSubviews
чтобы увидеть, в каком порядке они происходят.
Одна вещь, которую вы можете сделать, чтобы достичь аналогичного эффекта, это использовать dispatch_once
блок с once_token
это свойство вашего класса для выполнения анимации в viewDidLayoutSubviews
, Это обеспечит выполнение вашей анимации один раз для каждого экземпляра вашего класса после того, как произошла начальная компоновка представления. Это может быть то, что вы ищете.
Если бы вы могли предоставить больше своего кода контроллера представления или ссылки на github, я мог бы дать вам лучший, менее потенциально хакерский ответ о том, что происходит.