Краш при смене rootController с анимацией

Я использую эту функцию для изменения фактического корневого контроллера приложения:

class func setRootController(newController: UIViewController, animation: UIViewAnimationOptions? = nil) {

    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    if animation != nil {

        let currentController = appDelegate.window!.rootViewController!

        UIView.transition(from: currentController.view, to: newController.view, duration: 0.6, options: animation!, completion: { (completed) in
            appDelegate.window?.rootViewController = newController
        })


    } else {
        appDelegate.window?.rootViewController = newController
    }
}

Мой контроллер willAppear (вызывается дважды при использовании setRoot: 1 - при создании контроллера и начале анимации, 2 - в блоке завершения):

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    balanceView.bonuses = bonuses
}

Мой BalanceView (просто UIView) содержит бонусыStack (stackView) и бонусы var с didSet:

var bonuses: [Bonus]! {
    didSet {

        for subview in bonusesStack.arrangedSubviews {
            bonusesStack.removeArrangedSubview(subview)
            subview.removeFromSuperview()
        }

        bonuses.forEach { (bonus) in
            let bonusView = BonusBalanceView.loadFromXib(bonus: bonus)

            bonusesStack.addArrangedSubview(bonusView)
        }
    }
}

class func loadFromXib(bonus: Bonus) -> BonusBalanceView {
    let bonusView = Bundle.main.loadNibNamed(String(describing: BonusBalanceView.self), owner: nil, options: nil)?.first as! BonusBalanceView
    // some code here
    return bonusView
}

Когда willAppear вызывается во второй раз, код вылетает на строке subview.removeFromSuperview() (bcs во второй раз, superview равен нулю. Я пытаюсь добавить блок if для проверки superview, но по некоторым причинам он всегда выполняется O_o)

Если я прокомментирую/удалю эту строку (что не рекомендуется, представление bcs все еще находится в подвиде stackView), код вылетает в блоке завершения


person Viktor    schedule 19.01.2017    source источник


Ответы (1)


Проблема была в моем пользовательском представлении. Я переопределил метод отрисовки и работаю со слоями программно. В файле xib это представление содержит подпредставление. Каким-то образом ( ¯\_(ツ)_/¯ ) эти слои и подвид конфликтуют и приводят к сбою приложения

person Viktor    schedule 20.01.2017