Подтвердить что ты не робот

ContainerView с несколькими встроенными сегментами

Есть ли способ иметь один ContainerView с несколькими встроенными сегментами? Цель состоит в том, чтобы ContainerView удерживал несколько разных ViewControllers в зависимости от того, какие кнопки были нажаты; за один раз будет видно только одно. Я хочу использовать вставки segues, чтобы в Interface Builder раскадровки автоматически отображались в том же размере, что и ContainerView.

Я понимаю, что я могу вручную изменить размер других ViewControllers в InterfaceBuilder, но мне нужна автоматическая калибровка, предоставляемая встроенным segue. Если будет доступен другой способ сделать это, это тоже будет хорошо. Отсутствие нагрузки на viewDidLoad в порядке - как упоминалось ранее, показанный ViewController может меняться в зависимости от нажатых кнопок.

4b9b3361

Ответ 1

Нет, нет способа иметь несколько вложений в одном представлении контейнера. Один из способов сделать все настройки в IB - это сделать встроенный контроллер UITabBarController (с скрытой панелью вкладок). Затем вы можете иметь столько контроллеров на вкладках, сколько хотите, и переключиться на них в коде, используя свойство selectedIndex UITabBarController.

Ответ 2

Я нашел эту замечательную статью, которая точно объяснила, как это сделать: http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers

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

Ответ 3

Я понимаю, что этот вопрос немного устарел, но я хотел ответить, если вы все еще ищете или другие люди находят это. У меня была аналогичная проблема, и я работал над ней.

Короче говоря, у вас будет три уровня:
- контроллер внешнего вида ( "ExternalViewController" )
- диспетчер диспетчера представлений ( "ViewControllerManager" )
- контроллеры дочерних представлений, на которые вы действительно хотите переключиться ( "ChildViewController" )

Используйте представление контейнера в ExternalViewController с встроенным segue в ViewControllerManager. Сам ViewControllerManager будет удерживать другие ChildViewControllers программно, как описано в этой документации Apple, в частности раздел о добавлении и удалении дочернего элемента.

Когда вы добавляете контроллер дочернего представления, установите его фрейм таким же, как кадр ViewControllerManager (поскольку вы делаете это внутри ViewControllerManager, установите дочерний кадр равным self.view.frame). Разумеется, вам также понадобится логика и внешний элемент управления для переключения внутри ExternalViewController.

Надеюсь, это поможет!

Ответ 4

Да, я смог добиться того, что вы ищете, вдохновленного post @rdelmar. Что вам нужно сделать, так это вставить UITabBarViewController в вид контейнера. Затем вы программно выбираете, какой контроллер вы хотите представить. Вы также можете скрыть панель вкладок.

Контейнерный вид, косвенно содержащий больше просмотров

Если вы хотите, вы также можете скрыть полосы вкладок, видимые в файле раскадровки

Вы можете выбрать контроллер представления, который вы хотите представить, путем подкласса UITabBarController:

override func viewDidLoad() {
    super.viewDidLoad()
    self.selectedIndex = 1
}

Вы можете скрыть панель вкладок в вашем контроллере просмотра, вызвав self.tabBarController?.tabBar.hidden = true в viewDidLoad().

Ответ 5

Я достиг этого, используя -shouldPerformSegueWithIdentifier:sender:. У меня есть контейнер, которому передан объект, и в зависимости от типа этого объекта решает, какой контроллер дочернего представления должен отображаться.

Структура кажется немного более сложной, но позволяет контроллеру базового представления игнорировать различные типы задач, которые у меня есть, оставив это в контроллере представления контейнера. Контроллер представления контейнера имеет несколько видов контейнеров, которые выполняются только в зависимости от типа задачи.

Я не знаю, действительно ли вы можете выполнить встраивание segues вручную, вызвав -performSegueWithIdentifier:sender:, но это также может быть возможно.

Ответ 6

Я слишком долго боролся с этим. У меня был случай, когда у меня были разные, но похожие встроенные контроллеры табличных представлений, которые я хотел показать в зависимости от параметра, который был установлен в segue контроллеру представления. Что было сделано, чтобы вставить встроенный контейнер с IBOutlet в контроллере представления. Контейнер может иметь ограничения по размеру, установленные в IB. Однако не делайте никаких вложений в IB. Затем в viewDidLoad я программно добавляю правильный контроллер представления и привязываю его края к контейнеру вставки.

В основе этого подхода лежит следующий код (Swift 4):

extension UIView {
    func pinToParent() {
        self.translatesAutoresizingMaskIntoConstraints = false
        let attributes: [NSLayoutAttribute] = [.top, .bottom, .right, .left]
        NSLayoutConstraint.activate(attributes.map {
            NSLayoutConstraint(item: self, attribute: $0, relatedBy: .equal, toItem: self.superview, attribute: $0, multiplier: 1, constant: 0)
        })
    }
}

class ColorVC: UIViewController {

    @IBOutlet weak var tableContainer: UIView!
    var color : rgb = .red

    fileprivate var colorTableVC : ColorTableVC?

    override func viewDidLoad() {
        super.viewDidLoad()

        switch color {
        case .red:
            colorTableVC = RedTableVC.init(style: .plain)
        case .green:
            colorTableVC = GreenTableVC.init(style: .plain)
        case .blue:
            colorTableVC = BlueTableVC.init(style: .plain)
        }
        if let vc = colorTableVC {
            if (vc.view) != nil {
                self.addChildViewController(vc)
                tableContainer.addSubview(vc.view)
                vc.view.pinToParent()
                vc.didMove(toParentViewController: self)
            }
        }
    }
}

В ColorVC вы видите контейнер IBOutlet и параметр "color", заданный главным контроллером представления таблицы. RedTableVC, GreenTableVC и BlueTableVC все подклассы из ColorTableVC, который подклассифицирован из UITableViewController. Общее наследие позволяет мне использовать одну переменную colorTableVC, чтобы указать на любой из созданных экземпляров контроллеров. (Не совсем необходимо). Но это не позволяет дублировать код ниже, чтобы добавить представление в иерархию и подключить новый контроллер к представлению контейнера. В верхней части я сделал расширение на UIView, чтобы привязать взгляд к его родительским краям.

На следующем рисунке показано, как проект, в частности, контроллер вида справа, был установлен в IB. В этом примере я сделал высоту "встроенного" контроллера на половину высоты основного контроллера представления, поэтому при повороте устройства можно увидеть, что ограничения, установленные в IB, действительно применяются.

Установка встроенного контроллера IB

Ответ 7

В своем рабочем viewController перетащите пользовательский интерфейс и установите ограничение сверху, впереди, сзади, снизу в безопасную область (Iphone X serise).

Теперь поместите представление контейнера (представление содержимого) внутри этого UIView. Поместите столько представлений контента, сколько вы хотите, внутри этого UIView и вставьте в соответствующие ViewContrllers.

Работал на меня.