【问题标题】:how does a drag and drop view change programmatically in Xcode?拖放视图如何在 Xcode 中以编程方式更改?
【发布时间】:2015-02-25 19:59:44
【问题描述】:

当我将 UIView 对象拖放到 Xcode 中的情节提要中时,它们在哪里被实例化?当我从 ViewController 类中的故事板创建 UIView 对象的出口时,我到底在做什么?创建另一个也“指向情节提要中的对象”的 UIView 实例?因为如果我从插座更改一个属性,我也会更改情节提要中对象的相同属性。

【问题讨论】:

  • 插座不会创建另一个实例,它是指向您在情节提要中将在某个时候实例化的那个的指针。

标签: ios xcode


【解决方案1】:

情节提要只是 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,但只有极少数情况下您必须这样做

【讨论】:

    【解决方案2】:

    好的,首先你真的需要阅读 OOP 指导书(特别是你想要在 Objective-c 中编程的 Objective-c 书籍)。我会去苹果开发者图书馆开始了解 iOS 开发中的基本概念。

    对于您的问题,UIView 的实例可以通过两种方式实例化:

    1) 通过代码编写[[UIView alloc] init](也可以使用frame 初始化)

    2) 通过 IB (StoryBoard),当您将 UIView 拖放到 ViewController 中时,此 UIView 将在 ViewController 加载时被实例化。

    当您从UIView(或任何其他对象)创建IBOutlet 时,您基本上会创建一个指向您拖放到该UIVIewController 中的对象的指针。如果您更改该IBOutlet 的任何属性,则它正在更改IB 中该对象的属性。通过创建 IBOutlet 您根本没有初始化任何对象(您放置该对象的 ViewController 对此负责)您只创建指向该对象的指针。

    【讨论】:

      【解决方案3】:

      重点是http://en.wikipedia.org/wiki/Serialization。您的界面只是在 XML 文件(故事板、xib 或 nib)中序列化。

      【讨论】:

        猜你喜欢
        • 2016-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多