Я использую эту функцию для изменения фактического корневого контроллера приложения:
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), код вылетает в блоке завершения