Swift - Как связать два контроллера представления в один вид контейнера и переключиться между ними с помощью сегментированного элемента управления?

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

import UIKit

class PopularHistoryViewController: UIViewController {


    @IBOutlet weak var segmentedControl: UISegmentedControl!
    @IBOutlet weak var popularView: UIView!
    @IBOutlet weak var historyView: UIView!

    @IBAction func indexChanged(sender: UISegmentedControl) {
        switch segmentedControl.selectedSegmentIndex
        {
        case 0:
            NSLog("Popular selected")
            //show popular view
            popularView.hidden = false
            historyView.hidden = true
        case 1:
            NSLog("History selected")
            //show history view
            popularView.hidden = true
            historyView.hidden = false
        default:
            break; 
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

}

То, что я хочу, - это 1 вид контейнера, который содержит 2 вида контроллера, поэтому я могу их переключать, используя сегментированный элемент управления.

enter image description here

Пожалуйста, совет.

Ответ 1

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

let viewControllerIdentifiers = ["first", "second"]  // storyboard identifiers for the child view controllers

@IBAction func didChangeValue(sender: UISegmentedControl) {
    let newController = storyboard!.instantiateViewController(withIdentifier: viewControllerIdentifiers[sender.selectedSegmentIndex])
    let oldController = childViewControllers.last!

    oldController.willMove(toParentViewController: nil)
    addChildViewController(newController)
    newController.view.frame = oldController.view.frame

    transition(from: oldController, to: newController, duration: 0.25, options: .transitionCrossDissolve, animations: {
        // nothing needed here
    }, completion: { _ -> Void in
        oldController.removeFromParentViewController()
        newController.didMove(toParentViewController: self)
    })
}

Очевидно, это предполагает, что у вас уже есть первый контроллер детского представления уже на представлении (это легко сделать, если вы используете элемент управления контейнером в Interface Builder), и выбранное по умолчанию значение для UISegmentedControl соответствует. Вы также должны иметь идентификаторы раскадровки для этих двух дочерних сцен.

Для версии Swift 2 см. предыдущую версию этого ответа.

Ответ 2

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

Ответ 3

import UIKit

class ContactsView: UIViewController {

    @IBOutlet weak var segmentedControl: UISegmentedControl!
    @IBOutlet weak var privateView: UIView!
    @IBOutlet weak var publicView: UIView!

    @IBAction func segmentChanged(sender: UISegmentedControl) {
        switch segmentedControl.selectedSegmentIndex
        {
        case 0:
            privateView.hidden = false
            publicView.hidden = true
        case 1:
            privateView..hidden = true
            publicView.hidden = false
        default:
            break; 
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()   
    }

}