有没有办法让一个包含多个嵌入段的ContainerView?目的是让ContainerView根据按下的按钮保持几个不同的ViewControllers;一次只能看到一个。我想使用嵌入segues,这样在Interface Builder中,故事板会自动显示与ContainerView相同的大小。
我意识到我可以在InterfaceBuilder中手动调整其他ViewControllers的大小,但我想要嵌入segue提供的自动调整大小。如果可以采用另一种方式,那也没关系。没有在viewDidLoad上加载视图很好 - 如前所述,显示的ViewController可以根据按下的按钮而改变。
答案 0 :(得分:44)
不,没有办法将多个嵌入segue放到一个容器视图中。在IB中进行所有设置的一种方法是使嵌入式控制器成为UITabBarController(隐藏标签栏)。然后,您可以根据需要在选项卡中包含任意数量的控制器,并使用UITabBarController的selectedIndex属性在代码中切换到它们。
答案 1 :(得分:15)
我发现这篇精彩的文章解释了如何做到这一点:http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers
你得到你的容器并且可以调用任何后面的视图控制器,有一些设置可以将所有内容链接起来但是一旦完成,你就会得到一个仍然可用的故事板。
答案 2 :(得分:14)
我认识到这个问题有点老了,但我想回答一下你还在寻找或其他人发现这个问题。我有一个类似的问题,我在附近工作。
简而言之,你将有三层:
- 外部视图控制器(“ExternalViewController”)
- 视图控制器管理器(“ViewControllerManager”)
- 您实际想要切换的子视图控制器(“ChildViewController”)
在ExternalViewController中使用容器视图,并在ViewControllerManager中嵌入segue。然后,ViewControllerManager本身将按照in this Apple documentation所述以编程方式保存其他ChildViewControllers,特别是有关添加和删除子项的部分。
添加子视图控制器时,将其框架设置为与ViewControllerManager的框架相同(因为您在ViewControllerManager中执行此操作,将子框架设置为等于self.view.frame)。当然,您还需要一些逻辑和一个外部控件来进行ExternalViewController内部的切换。
希望这有帮助!
答案 3 :(得分:14)
是的,我能够通过@rdelmar帖子实现您正在寻找的灵感。您需要做的是在容器视图中嵌入UITabBarViewController
。然后以编程方式选择要呈现的控制器。您可能还想隐藏标签栏。
如果您需要,还可以隐藏故事板文件中显示的标签栏
您可以通过继承UITabBarController来选择要呈现的视图控制器:
override func viewDidLoad() {
super.viewDidLoad()
self.selectedIndex = 1
}
您可以通过在viewDidLoad()中调用self.tabBarController?.tabBar.hidden = true
来隐藏视图控制器中的标签栏。
答案 4 :(得分:2)
我通过使用-shouldPerformSegueWithIdentifier:sender:
实现了这一目标。我有一个传递一个对象的容器,根据该对象的类型决定要显示哪个子视图控制器。
结构看起来有点过于复杂但允许基本视图控制器忽略我拥有的不同类型的任务,将其留给容器视图控制器。 然后,容器视图控制器具有多个容器视图,这些视图仅根据任务类型执行。
我不知道你是否可以通过调用-performSegueWithIdentifier:sender:
手动执行嵌入segue,但这也是一种可能性。
答案 5 :(得分:2)
我也在这方面挣扎了很长时间。我有这样的情况,我有不同但类似的嵌入式表视图控制器,我想根据在视图控制器的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和"颜色"由主表视图控制器设置的参数。 RedTableVC,GreenTableVC和BlueTableVC都是ColorTableVC的子类,它是UITableViewController的子类。共同的遗产让我使用了一个" colorTableVC"变量指向任何实例化的控制器。 (不完全必要)。但这确实避免了重复下面的代码来在heirarchy中添加视图并将新控制器固定到容器视图。在顶部,我在UIView上做了一个扩展,将视图固定到其父级边缘。
下图显示了如何在IB中设置项目,尤其是右侧的视图控制器。在这个例子中,我创造了"嵌入式"的高度。控制器是主视图控制器高度的一半 - 因此当您旋转设备时,可以看到确实应用了IB中设置的约束。
答案 6 :(得分:0)
在工作的viewController中,拖动uiview并将约束设置为顶部,前导,尾随,底部到安全区域(Iphone X系列)。
现在将Container视图(内容视图)放在该UIView中。 在该UIView中放入任意数量的内容视图,并分别嵌入到ViewContrllers中。
为我工作。