How to add a subview that has its own UIViewController in Objective-C?
我正在与拥有自己的
所以,我要退后一步,在这里迈出一些小步。下面是我的工具
我想用
下面是迄今为止我掌握的代码。我所要做的就是显示蓝色视图,粉色视图在其中。从我所看到的情况来看,我应该能够只使用
除了在VIEWDIDLOAD中显示蓝色视图外,此代码不用于其他任何操作。
idutilityviewcontroller.h(idutilityviewcontroller.h)
1 2 3 4 5 | #import <UIKit/UIKit.h> @interface IDUtilityViewController : UIViewController @property (strong, nonatomic) IBOutlet UIView *utilityView; @end |
idutilityviewcontroller.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #import"IDUtilityViewController.h" #import"IDAboutViewController.h" @interface IDUtilityViewController () @property (nonatomic, strong) IDAboutViewController *aboutVC; @end @implementation IDUtilityViewController - (void)viewDidLoad { [super viewDidLoad]; self.aboutVC = [[IDAboutViewController alloc]initWithNibName:@"AboutVC" bundle:nil]; [self addChildViewController:self.aboutVC]; [self.aboutVC didMoveToParentViewController:self]; [self.utilityView addSubview:self.aboutVC.aboutView]; } @end |
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————---
self.aboutvc.aboutview为零。但我把它装进了
这篇文章可以追溯到现代iOS的早期,通常有最新的语法,比如目前的swift 4。如果你开始使用iOS、自动布局等,它会让你前进。好的。
在今天的iOS中,"一切都是容器视图"。这是你今天制作应用程序的基本方式。好的。
应用程序可能非常简单,只有一个视图。但即使在这种情况下,屏幕上的每个"东西"都是一个容器视图。好的。
就这么简单…好的。(a)将容器视图拖到场景中…
将容器视图拖到场景视图中。(就像你要拖入一个uibutton一样。)好的。
容器视图是这张图中的褐色部分。它实际上在场景视图中。好的。
好的。
当您将容器视图拖动到场景视图中时,Xcode会自动为您提供两种功能:好的。
在场景视图中得到容器视图,好的。
你会得到一个全新的
这两个与"共济会符号"有关-解释如下!好的。(b)点击新的视图控制器(Xcode为你在白色区域的某个地方制作的新东西,而不是你场景中的东西)。还有,换个班!
这真的很简单。好的。
你完了。好的。
这里也有同样的东西可以直观地解释。好的。
注意
注意
好的。
点击b.(那是b-不是a!)好的。
去右上角的检查员那里。注意上面写着"uiviewcontroller"好的。
[3]好的。
将其更改为您自己的自定义类,这是一个uiviewController。好的。
好的。
所以,我有一个很快的
好的。
所以当它在inspector中说"uiviewcontroller"时,我输入了"snap"。好的。
(和往常一样,当您开始键入"snap…"时,xcode将自动完成"snap"。)好的。
就这些了-你完了。好的。如何将容器视图更改为表视图。
所以当你点击添加一个容器视图时,苹果会自动给你一个链接视图控制器,位于故事板上。好的。
实际情况(2017):默认情况下,它将成为
那太傻了:它应该问你需要哪种类型。例如,通常需要表视图。以下是如何将其更改为不同的内容:好的。< Buff行情>
在编写时,Xcode默认提供一个
(i)将容器视图拖到场景中。看看故事板上的uiviewcontroller,Xcode默认提供给您。好的。
(ii)将新的
(iii)单击场景内的容器视图。单击连接检查器。请注意,有一个"触发的segue"。将鼠标悬停在"触发的segue"上,注意xcode会突出显示所有不需要的uiviewcontroller。好的。
(iv)点击"X"实际删除触发的SEgue。好的。
(v)从触发的SEgue中拖动(只有VIEWDIDLOAD选项)。在情节提要中拖动到新的uiCollectionViewController。放开,弹出一个窗口。必须选择"嵌入"。好的。
(vi)只需删除所有不需要的uiviewcontroller。你完了。好的。< /块引用>
短版本:删除不需要的uiviewcontroller。在故事板上放一个新的
您将拥有其中一个"正方形"共济会符号:它位于连接容器视图和视图控制器的"Bendy线"上。好的。
"共济会符号"就是世格。好的。
好的。
点击"共济会符号"选择世格。好的。
向右看。好的。
必须为SEgue键入文本标识符。好的。
你决定名字。它可以是任何文本字符串。明智的选择通常是"segueclassname"。好的。
如果你遵循这个模式,你的所有段将被称为segueclockview、seguepersonselector、seguesnap、seguecards等等。好的。
接下来,在哪里使用文本标识符?好的。如何连接到子控制器…
然后,在代码中,在整个场景的视图控制器中执行以下操作。好的。
假设场景中有三个容器视图。每个容器视图包含一个不同的控制器,比如"快照"、"时钟"和"其他"。好的。
最新的swift3语法(2017)好的。
1 2 3 4 5 6 7 8 9 10 11 12 | var snap:Snap? var clock:Clock? var other:Other? override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if (segue.identifier =="segueSnap") { snap = (segue.destination as! Snap) } if (segue.identifier =="segueClock") { clock = (segue.destination as! Clock) } if (segue.identifier =="segueOther") { other = (segue.destination as! Other) } } |
就这么简单。您可以使用
假设您"在"已放置在容器视图中的控制器中(示例中为"捕捉")。好的。
找到你上面的"老板"视图控制器(示例中的"破折号")可能会让人困惑。幸运的是,这很简单:好的。
1 2 3 4 5 6 7 8 9 10 | // Dash is the overall scene. // Here we are in Snap. Snap is one of the container views inside Dash. class Snap { var myBoss:Dash? override func viewDidAppear(_ animated: Bool) { // MUST be viewDidAppear super.viewDidAppear(animated) myBoss = self.parent as? Dash } |
关键:仅适用于
你完了。好的。重要提示:这只适用于容器视图。
重要的高级提示:不要忘记,这只适用于容器视图。好的。
现在,使用故事板标识符,只需在屏幕上弹出新的视图(而不是在Android开发中)是司空见惯的。所以,假设用户想要编辑一些东西…好的。
1 2 3 4 5 6 | // let's just pop a view on the screen. // this has nothing to do with container views // let e = ...instantiateViewController(withIdentifier:"Edit") as! Edit e.modalPresentationStyle = .overCurrentContext self.present(e, animated: false, completion: nil) |
当使用容器视图时,可以保证Dash将是Snap的父视图控制器。好的。
但是,当您使用InstantationViewController时,情况并不一定是这样的。好的。
令人困惑的是,在iOS中,父视图控制器与实例化它的类无关。(可能是相同的,但通常是不同的。)
(对于InstantViewController模式中的类似结果,必须使用协议和委托,记住委托将是弱链接。)好的。PrepareForSegue名字不好…
值得注意的是,"PrepareForSegue"是一个很坏的名字!好的。
"PrepareForSegue"用于两个目的:加载容器视图和在场景之间进行分隔。好的。
但在实践中,你很少在场景之间徘徊!当然,几乎每个应用程序都有许多容器视图。好的。
如果"PrepareForSegue"被称为类似"LoadingContainerView"的东西,那就更有意义了。好的。不止一个…
一个常见的情况是:屏幕上有一个小区域,您希望在其中显示许多不同视图控制器中的一个。例如,四个小部件之一。好的。
最简单的方法是:让四个不同的容器视图都位于相同的区域。在您的代码中,只需隐藏所有四个选项,然后打开您希望看到的那个选项。好的。
在故事板上,有一个空的"holder"uiview,它只保存四个容器视图。然后,通过调整大小或移动"支架",可以同时调整或移动所有四个支架。在您的代码中,只需拥有四个
正如Simplgy在下面指出的那样,"IOS9的故事板引用使得容器视图更加令人敬畏。您可以在任何需要的地方定义可重用视图(控制器),并从多个模块化故事板中的任何容器视图引用它。"好的。
同样要注意的是-相当令人困惑-通常今天您只是不必费心容器视图!好的。
在许多情况下,您只需使用cx1(2)。好的。
但请注意上面解释的关于
如果您使用故事板引用来使用
相比之下,使用"固定"的容器视图是非常简单的,您可以立即连接到父级和子级之间,如上面所述。好的。好啊。
我看到两个问题。首先,由于你在故事板中制作控制器,你应该用
1 2 3 4 5 6 7 8 9 10 | - (void)viewDidLoad { [super viewDidLoad]; self.aboutVC = [self.storyboard instantiateViewControllerWithIdentifier:@"aboutVC"]; // make sure you give the controller this same identifier in the storyboard [self addChildViewController:self.aboutVC]; [self.aboutVC didMoveToParentViewController:self]; self.aboutVC.view.frame = self.utilityView.bounds; [self.utilityView addSubview:self.aboutVC.aboutView]; } |