- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在努力处理具有自己的 UIViewControllers
的 subview 。我有一个带有 View (浅粉色)的 UIViewController
和 toolbar
上的两个按钮。我希望在按下第一个按钮时显示蓝色 View ,并在按下第二个按钮时显示黄色 View 。如果我只想显示 View 应该很容易。但是蓝色 View 将包含一个表,因此它需要它自己的 Controller 。那是我的第一个类。我从 this SO question 开始,在那里我了解到我需要一个 table 的 Controller 。
所以,我要备份并在这里采取一些婴儿步骤。下面是我的 Utility ViewController
(主 View Controller )和其他两个 Controller (蓝色和黄色)的简单起点的图片。想象一下,当 Utility ViewController
(主 View )首次显示时,蓝色(默认) View 将显示在粉红色 View 所在的位置。用户将能够单击这两个按钮来回切换,并且永远不会显示粉红色 View 。我只希望蓝色 View 去粉红色 View 所在的地方,黄色 View 去粉红色 View 所在的地方。我希望这是有道理的。
我正在尝试使用 addChildViewController
。据我所知,有两种方法可以做到这一点: storyboard
或 addChildViewController
中的容器 View 以编程方式。我想以编程方式进行。我不想使用 NavigationController
或标签栏。我只想添加 Controller ,并在按下相关按钮时将正确的 View 插入粉红色 View 中。
下面是我到目前为止的代码。我想要做的就是在粉红色 View 所在的位置显示蓝色 View 。从我所看到的,我应该只能 addChildViewController
和 addSubView。这段代码不是为我做的。我的困惑越来越好。有人可以帮助我在粉红色 View 所在的位置显示蓝色 View 吗?
除了在 viewDidLoad 中显示蓝色 View 之外,此代码不打算执行任何其他操作。
IDUtilityViewController.h
#import <UIKit/UIKit.h>
@interface IDUtilityViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIView *utilityView;
@end
#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
storyboard
中。我还需要实例化它吗?
最佳答案
这篇文章可以追溯到现代 iOS 的早期。它使用当前信息和当前 Swift 语法进行更新。
在今天的 iOS 中 “一切都是容器 View ” 。这是您今天制作应用程序的基本方式。
一个应用程序可能非常简单,以至于它只有一个屏幕。但即使在这种情况下,屏幕上的每个“事物”都是一个容器 View 。
就这么简单...
版本说明
2020 年。如今,您通常只需从单独的 Storyboard加载容器 View ,这非常容易。在这篇文章的底部有解释。如果您不熟悉容器 View ,请先熟悉“经典风格”(“相同 Storyboard”)容器教程。
2021. 更新了语法。使用了 SO 新的“###”漂亮的标题。有关从代码加载的更多详细信息。
(A) 将容器 View 拖到您的场景中...
将容器 View 拖到场景 View 中。 (就像您将拖入任何元素(例如 UIButton)一样。)
容器 View 是这张图片中的棕色东西。它实际上是 里面的 你的 场景 View 。
当您将容器 View 拖到场景 View 中时,Xcode 会自动为您提供 两件事 :
UIViewController
也就是 就在你的 Storyboard 白色的某个地方。(A)
。
(B)
。
Snap
,它是一个
UIViewController
。
UIViewController
。
At the time of writing, Xcode gives you a
UIViewController
by default. Let's say you want aUICollectionViewController
instead:(i) Drag a container view in to your scene. Look at the UIViewController on the storyboard which Xcode gives you by default.
(ii) Drag a new
UICollectionViewController
to anywhere on the main white area of the storyboard.(iii) Click the container view inside your scene. Click the connections inspector. Notice there is one "Triggered Segue". Mouse over the "Triggered Segue" and notice that Xcode highlights all of the unwanted UIViewController.
(iv) Click the "x" to actually delete that Triggered Segue.
(v) DRAG from that Triggered Segue (viewDidLoad is the only choice). Drag across the storyboard to your new UICollectionViewController. Let go and a pop-up appears. You must select embed.
(vi) Simply delete all of the unwanted UIViewController. You're done.
UICollectionViewController
。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) }
}
就这么简单。您可以使用 prepareForSegue
调用连接一个变量来引用 Controller 。// 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 = parent as? Dash
}
严重: 仅适用于 viewDidAppear
或更高版本。在 viewDidLoad
中不起作用。 // 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)
使用容器 View 时, 保证 Dash 将成为 Snap 的父 View Controller 。self.parent
模式是 仅用于 0.9141 容器 0.9141 View Map
类的 View Controller 。let map = UIStoryboard(name: "Map", bundle: nil)
.instantiateViewController(withIdentifier: "MapID")
as! Map
在你的主场景中有一个普通的 UIView:@IBOutlet var dynamicContainerView: UIView!
Apple 解释 here 添加动态容器 View 必须做的四件事addChild(map)
map.view.frame = dynamicContainerView.bounds
dynamicContainerView.addSubview(map.view)
map.didMove(toParent: self)
(以该顺序。)map.willMove(toParent: nil)
map.view.removeFromSuperview()
map.removeFromParent()
(也是按这个顺序。)就是这样。dynamicContainerView
只是一个固定 View 。它不会改变或调整大小。这只有在您的应用程序从不旋转或其他任何东西时才有效。通常,您必须添加四个常用约束,以便在调整大小时将 map.view 保持在 dynamicContainerView 中。事实上,这是在任何 iOS 应用程序中都需要的“世界上最方便的扩展程序”,extension UIView {
// it's basically impossible to make an iOS app without this!
func bindEdgesToSuperview() {
guard let s = superview else {
preconditionFailure("`superview` nil in bindEdgesToSuperview")
}
translatesAutoresizingMaskIntoConstraints = false
leadingAnchor.constraint(equalTo: s.leadingAnchor).isActive = true
trailingAnchor.constraint(equalTo: s.trailingAnchor).isActive = true
topAnchor.constraint(equalTo: s.topAnchor).isActive = true
bottomAnchor.constraint(equalTo: s.bottomAnchor).isActive = true
}
}
因此,在任何真正的应用程序中,上面的代码都是:addChild(map)
dynamicContainerView.addSubview(map.view)
map.view.bindEdgesToSuperview()
map.didMove(toParent: self)
(有些人甚至做了一个扩展 .addSubviewAndBindEdgesToSuperview()
以避免出现一行代码!)map
动态添加到持有人,现在您想将其删除。正确且唯一的顺序是:map.willMove(toParent: nil)
map.view.removeFromSuperview()
map.removeFromParent()
通常你会有一个持有者 View ,并且你想要交换不同的 Controller 。所以:var current: UIViewController? = nil
private func _install(_ newOne: UIViewController) {
if let c = current {
c.willMove(toParent: nil)
c.view.removeFromSuperview()
c.removeFromParent()
}
current = newOne
addChild(current!)
holder.addSubview(current!.view)
current!.view.bindEdgesToSuperview()
current!.didMove(toParent: self)
}
关于objective-c - 如何在 Objective-C 中添加一个拥有自己的 UIViewController 的 subview ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23399061/
我是一名优秀的程序员,十分优秀!