【问题标题】:Swift - How to link two view controllers into one container view and switch between them using segmented control?Swift - 如何将两个视图控制器链接到一个容器视图中并使用分段控制在它们之间切换?
【发布时间】:2015-01-17 19:50:26
【问题描述】:

我有一个包含 1 个分段控件和 2 个 UI 视图的视图控制器。但我认为更新 UI 视图以增强未来编辑功能太复杂了。我正在使用隐藏方法。

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 个控制器视图的容器视图,因此我可以使用分段控制来切换它们。

【问题讨论】:

  • 你实际上并没有说问题是什么,你的代码显示了两个视图
  • 我想要的是我可以在容器视图中链接两个视图控制器。
  • 看一下标签栏控制器 - 尽管外观不同,但它可以“开箱即用”地执行您想要的操作

标签: ios swift xcode6


【解决方案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 版本,请参阅 previous revision of this answer

【讨论】:

  • 您还可以通过将两个视图控制器实例化到 viewDidLoad 或类似的属性中来将它们保留在内存中 - 然后您可以在保持状态的情况下在它们之间切换,甚至在第一次切换时延迟加载正如UITabBarController 所做的那样
  • 同意。如果 Dato' 这样做,我肯定会建议延迟加载方法。
  • 我遇到致命错误:在展开可选值时意外发现 nil
  • 哪一行?您是否为两个子场景指定了故事板标识符?它们是否与您在上面使用的匹配(例如我的示例中的“第一”和“第二”)?
  • 抱歉撞了!我有同样的错误。引发此可选错误的行是您将值分配给 oldController 的行。 let oldController = childViewControllers.last! as UIViewController
【解决方案2】:

我不久前曾广泛尝试过这样做。由于某种原因,隐藏的属性对我不起作用,并且容器视图似乎没有更新。我知道这不是理想的解决方案,但我最终创建了两个容器视图并使用分段控件来更改容器视图的 alpha。同样,并不理想,但效果很好。

【讨论】:

    【解决方案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()   
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 2015-10-23
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多