ios 具有多个嵌入转场的 ContainerView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18407714/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ContainerView with multiple embed segues
提问by Steve Haley
Is there a way to have a single ContainerView with multiple embed segues? The aim is for a ContainerView to hold a few different ViewControllers depending on what buttons have been pressed; only one is going to be visible at a time. I want to use embed segues so that in Interface Builder the storyboards are automatically shown at the same size as the ContainerView.
有没有办法让单个 ContainerView 具有多个嵌入 segues?目的是让 ContainerView 根据按下的按钮来保存几个不同的 ViewController;一次只能看到一个。我想使用嵌入转场,以便在 Interface Builder 中故事板自动以与 ContainerView 相同的大小显示。
I realise that I can manually resize the other ViewControllers in InterfaceBuilder, but I want the automatic sizing provided by the embed segue. If another way of doing that is available, that would be fine too. Not having the views load on viewDidLoad is fine - as mentioned earlier, the shown ViewController can change depending on the buttons pressed.
我意识到我可以在 InterfaceBuilder 中手动调整其他 ViewControllers 的大小,但我想要由 embed segue 提供的自动调整大小。如果可以使用另一种方法,那也可以。没有在 viewDidLoad 上加载视图很好 - 如前所述,显示的 ViewController 可以根据按下的按钮而改变。
回答by rdelmar
No, there is no way to have multiple embed segues to one container view. One way to do all the setup in IB, would be to make the embedded controller a UITabBarController (with the tab bar hidden). You can then have as many controllers in the tabs as you want, and switch to them in code using the selectedIndex property of UITabBarController.
不,无法在一个容器视图中设置多个嵌入转场。在 IB 中完成所有设置的一种方法是使嵌入式控制器成为 UITabBarController(隐藏标签栏)。然后,您可以根据需要在选项卡中拥有任意数量的控制器,并使用 UITabBarController 的 selectedIndex 属性在代码中切换到它们。
回答by Andrej
Yes, I was able to achieve what you're looking for inspired by @rdelmar post. What you need to do is to embed a UITabBarViewController
into your container view. Then you programmatically choose which controller you like to present. You might also like to hide the tab bar.
是的,在@rdelmar 帖子的启发下,我能够实现您正在寻找的东西。您需要做的是将 a 嵌入UITabBarViewController
到您的容器视图中。然后您以编程方式选择您喜欢展示的控制器。您可能还想隐藏标签栏。
If you want you can also hide the tab bars seen in the storyboard file
如果您愿意,您还可以隐藏故事板文件中的标签栏
You can choose the view controller you want to present by subclassing the UITabBarController:
您可以通过继承 UITabBarController 来选择要呈现的视图控制器:
override func viewDidLoad() {
super.viewDidLoad()
self.selectedIndex = 1
}
You can hide the tab bar in your view controller by calling self.tabBarController?.tabBar.hidden = true
in viewDidLoad().
您可以通过调用self.tabBarController?.tabBar.hidden = true
viewDidLoad()来隐藏视图控制器中的标签栏。
回答by Kanjiroushi
I found this wonderful article that explained exactly how to do it: http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers
我发现这篇精彩的文章详细解释了如何做到这一点:http: //sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers
you get your container and can call any view controller behind, there is a bit of set up to have everything linked but once done, you get a still useable storyboard.
你得到你的容器并且可以调用后面的任何视图控制器,有一些设置来链接所有的东西,但是一旦完成,你就会得到一个仍然可用的故事板。
回答by UberJason
I recognize this question is a bit old, but I wanted to answer in case you're still looking or other people find this. I had a similar issue and I worked around it.
我知道这个问题有点老了,但我想回答一下,以防您仍在寻找或其他人发现这个问题。我有一个类似的问题,我解决了它。
In short, you'll have three layers:
- an external view controller ("ExternalViewController")
- a view controller manager ("ViewControllerManager")
- the child view controllers you actually want to be switching between ("ChildViewController")
简而言之,您将拥有三层:
- 外部视图控制器(“ExternalViewController”)
- 视图控制器管理器(“ViewControllerManager”)
- 您实际想要在其间切换的子视图控制器(“ChildViewController”)
Use a container view in ExternalViewController with an embed segue to the ViewControllerManager. ViewControllerManager itself would then hold other ChildViewControllers programmatically as described in this Apple documentation, specifically the section on adding and removing a child.
在 ExternalViewController 中使用容器视图,并嵌入到 ViewControllerManager 中。ViewControllerManager 本身将按照Apple 文档中的描述以编程方式保存其他 ChildViewController ,特别是有关添加和删除子项的部分。
When you add a child view controller, set its frame to be the same as the ViewControllerManager's frame (since you're doing this inside the ViewControllerManager, set the child's frame equal to self.view.frame). You will also need some logic and an external control to do the switching inside of ExternalViewController, of course.
添加子视图控制器时,将其框架设置为与 ViewControllerManager 的框架相同(因为您是在 ViewControllerManager 内部执行此操作,因此将子视图控制器的框架设置为等于 self.view.frame)。当然,您还需要一些逻辑和外部控件来在 ExternalViewController 内部进行切换。
Hope this helps!
希望这可以帮助!
回答by Fábio Oliveira
I've achieved that by making use of -shouldPerformSegueWithIdentifier:sender:
. I have a container that is passed an object and depending on the type of this object decides which child view controller to show.
我已经通过使用-shouldPerformSegueWithIdentifier:sender:
. 我有一个容器,它传递了一个对象,并根据该对象的类型决定要显示哪个子视图控制器。
The structure seems a little over complicated but allows the base view controller to ignore the different types of tasks I have, leaving that to the container view controller. The container view controller has then multiple container views which segues are only performed depending on the type of task.
该结构似乎有点过于复杂,但允许基本视图控制器忽略我拥有的不同类型的任务,将其留给容器视图控制器。容器视图控制器然后有多个容器视图,这些视图仅根据任务类型执行。
I don't know if you can actually perform the embed segues manually by calling -performSegueWithIdentifier:sender:
but that could also be a possibility.
我不知道您是否可以通过调用手动执行嵌入转场,-performSegueWithIdentifier:sender:
但这也有可能。
回答by anorskdev
I struggled with this for a long time, too. I had the case where I had different, but similar embedded table view controllers that I wanted to show depending on a parameter that was set in the segue to the view controller. What worked was to put in the embedded container with an IBOutlet in the view controller. The container can have size constraints set in IB. However, don't make any embed segues in IB. Then in viewDidLoad, I programmatically add the correct view controller and pin its edges to the embed container.
我也为此挣扎了很长时间。我遇到过我想根据在视图控制器的 segue 中设置的参数显示的不同但相似的嵌入式表视图控制器的情况。有效的是在视图控制器中放入带有 IBOutlet 的嵌入式容器。容器可以在 IB 中设置大小限制。但是,不要在 IB 中进行任何嵌入转场。然后在 viewDidLoad 中,我以编程方式添加正确的视图控制器并将其边缘固定到嵌入容器。
The heart of this approach is seen in the following code (Swift 4):
这种方法的核心在以下代码(Swift 4)中可见:
extension UIView {
func pinToParent() {
self.translatesAutoresizingMaskIntoConstraints = false
let attributes: [NSLayoutAttribute] = [.top, .bottom, .right, .left]
NSLayoutConstraint.activate(attributes.map {
NSLayoutConstraint(item: self, attribute: ##代码##, relatedBy: .equal, toItem: self.superview, attribute: ##代码##, 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)
}
}
}
}
In the ColorVC, one sees the container IBOutlet and the "color" parameter set by the main table view controller. The RedTableVC, GreenTableVC, and BlueTableVC are all subclassed from ColorTableVC which is sub-classed from UITableViewController. The common heritage lets me use one "colorTableVC" variable to point to any of the instantiated controllers. (Not entirely necessary). But this does avoid duplicating code below to add the view in the heirarchy and pin the new controller to the container view. At the top, I made an extension on UIView to pin a view to its parents edges.
在 ColorVC 中,可以看到容器 IBOutlet 和主表视图控制器设置的“颜色”参数。RedTableVC、GreenTableVC 和 BlueTableVC 都是 ColorTableVC 的子类,而 ColorTableVC 又是 UITableViewController 的子类。共同的遗产让我可以使用一个“colorTableVC”变量来指向任何实例化的控制器。(并非完全必要)。但这确实避免了复制下面的代码以在层次结构中添加视图并将新控制器固定到容器视图。在顶部,我对 UIView 进行了扩展以将视图固定到其父边缘。
The following image shows how the project and particularly the view controller on the right was set up in IB. For this example, I made the height of the "embedded" controller half the height of the main view controller - so when you rotate the device, one can see that the constraints set in IB are indeed applied.
下图显示了如何在 IB 中设置项目,尤其是右侧的视图控制器。在这个例子中,我将“嵌入式”控制器的高度设为主视图控制器高度的一半——所以当你旋转设备时,可以看到确实应用了 IB 中设置的约束。
回答by JobLess
In your working viewController drag a uiview and set constraint to top, leading, trailing, bottom to safe area (Iphone X serise).
在您的工作视图控制器中拖动一个 uiview 并将约束设置为顶部、前导、尾随、底部到安全区域(Iphone X 系列)。
Now put Container view (Content View) inside that UIView. Put as many content views as you want inside that UIView and embed to respective ViewContrllers.
现在把容器视图(内容视图)放在那个 UIView 里面。在 UIView 中放入任意数量的内容视图并嵌入到相应的 ViewContrllers。
Worked for me.
为我工作。