Анимация представления на 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, я мог бы дать вам лучший, менее потенциально хакерский ответ о том, что происходит.

Другие вопросы по тегам