Как правильно обрабатывать содержание контроллера представления в iOS (~ Swift 4.2)

Стремясь поддерживать более сложные интерфейсы, Apple представила разработчикам возможность управлять включением контроллера представления в iOS 5. Это позволяет приложениям отказаться от использования стандартных контроллеров представления, таких как UITabViewController, UINavigationController и создавать более интересный и богатый интерфейс.

Тем не менее, идея управления несколькими дочерними контроллерами представлений кажется разработчикам пугающей, и по уважительной причине. Это просто не очень простая концепция, но она того стоит, если вы хотите, чтобы ваши контроллеры представления были как можно более компактными.

Добавление контроллера представления в качестве дочернего элемента другого контроллера представления включает несколько шагов, и отказ от включения любого из них в поток может означать потенциальные ошибки. Важно ответственно относиться к сдерживанию!

Предположим, у нас есть объект DadViewController, который хотел бы добавить объект KidViewController в качестве своего дочернего объекта и представить его в своем интерфейсе.

У объектов UIViewController есть свойство с именем children, которое представляет собой автоматически поддерживаемый массив контроллеров представления.

Первым шагом dad будет вызов add(kid:) метода с передачей kid. Ссылка на этот экземпляр будет добавлена ​​в массив children.

class DadViewController: UIViewController {
    func add(_ kid: KidViewController) {
        addChild(kid)
    }
    
    // ...
}

Важно понимать, что это действие приведет к запуску методов kid’s viewDidLoad() и willlMove(toParent:).

Затем мы должны вручную добавить представление kid’s в качестве подчиненного представления иерархии собственных представлений dad’s.

class DadViewController: UIViewController {
    func add(_ kid: KidViewController) {
        addChild(kid)
        view.addSubview(kid.view)
    }
    // ...
}

Именно в этот момент срабатывают методы kid’s viewWillAppear() и viewDidAppear().

Наконец, вы несете ответственность за вызов kid didMove(toParent:) метода вручную, передачу экземпляра родительского контроллера представления, а также установку правильного кадра для его свойство view.

class DadViewController: UIViewController {
    func add(_ kid: KidViewController) {
        addChild(kid)
        view.addSubview(kid.view)
        kid.didMove(toParent: self)
        kid.view.frame = CGRect(x: 0, y: 100, width: 10, height: 10)
    }
    // ...
}

Удаление дочернего контроллера представления из родительского контроллера представления происходит по аналогичной схеме:

class DadViewController: UIViewController {
    func remove(_ kid: KidViewController) {
        kid.willMove(toParent: nil)
        kid.view.removeFromSuperview()
        kid.removeFromParent()
    }
// ...
}

Простой!

let dad = DadViewController()
let kid = KidViewController()
dad.add(kid)

Помните, что если вы используете представления контейнера в раскадровке, все это обрабатывается автоматически!

Наша миссия в Fishbrain - создать лучший инструмент для людей, которые любят рыбалку. Мы верим, что если вам нравится то, что вы делаете в окружении вдохновляющих коллег, в атмосфере роста и развития, вы добьетесь больших успехов. См. careers.fishbrain.com для вакансий!