情节提要只是 xml 文件的视觉外观。在编译期间,故事板将被编译为 .xib 文件,并且在运行时代码将被执行,创建例如一个 UIButton 实例并将其分配给 IBOutlet 属性。
当您在视图控制器中创建一个插座时(您的意思是 cmd-drag-and-drop 到 vc 的界面,不是吗?),您没有实例化对象,这将在运行时发生。它只是一种特殊的属性,将被创建并连接到 Interface Builder 中的可见元素。特殊之处在于它被归为 IBOutlet。 IBOutlet 的意思是“这是一个属性,并且 Interface Builder 中的 UIView 已(或至少可以)附加到它”。
让我们做一个简短的例子:
你有一个带有按钮的 UI,它连接到你的 VC
你的VC:
#import "MyViewController.h"
@interface MyViewController ()
@property (weak, nonatomic) IBOutlet UIButton *myButton;
@end
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
@end
在 xml 视图中打开故事板将显示 ViewController 已连接到 UI 元素:
<scene sceneID="s5g-Va-rCL">
<objects>
<viewController id="xkG-tv-x1p" customClass="MyViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="zM9-gD-jvN"/>
<viewControllerLayoutGuide type="bottom" id="rpt-g7-UaO"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="bJ6-Zc-BUd">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iHE-Sb-Hes">
<rect key="frame" x="277" y="60" width="46" height="30"/>
<state key="normal" title="Button">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
<connections>
<outlet property="myButton" destination="iHE-Sb-Hes" id="0tI-Cr-cDZ"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dWo-Es-1mt" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1092" y="628"/>
</scene>
这里最有趣的是下面这行:
<outlet property="myButton" destination="iHE-Sb-Hes" id="0tI-Cr-cDZ"/>
目标“iHE-Sb-Hes”是上面几行声明的按钮 id。这是 UIViewController 和 UIView 之间的连接定义,将在运行时编译为代码并实例化。
通常,您不必担心如何详细创建 UI 元素。当一个 UIViewController 被推送时,它的视图将被加载并且 viewDidLoad: 将被调用并且你所有的 UI 对象都在那里。您可以编写自己的视图加载器,是的,您可以在代码中创建整个 UI。
对于自定义视图加载覆盖 loadView,如下所述:
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html
总结一下:
- 虽然我在这里引用了XML,但通常不要碰故事板的xml,因为它是由IB编辑的。 git 合并很好,但不要像在 Android 或 Windows XAML 上那样开始用纯 xml 编写 UI 视图
- 运行时将生成您在 IB 中定义的所有视图对象,这应该没问题。 99.99%,你应该开始在生命周期钩子中使用你的代码,比如 viewDidLoad: 或 viewWillAppear:
- 如果您对默认的 UIView 加载不满意,请覆盖 UIViewController 的 loadView,但只有极少数情况下您必须这样做