xib 在 Xamarin 中生成代码.xib Code Generation in Xamarin.iOS

重要

本文档说明 Visual Studio for Mac 仅与 Xcode 的 Interface Builder 集成,因为 Xamarin Designer for iOS 未使用操作和插座。This document explains Visual Studio for Mac's integration with Xcode's Interface Builder only, as Actions and Outlets are not used in the Xamarin Designer for iOS. 有关 iOS 设计器的详细信息,请查看Ios 设计器文档。For more information on the iOS Designer, please review the iOS Designer document.

Apple Interface Builder 工具("IB")可用于直观地设计用户界面。The Apple Interface Builder tool ("IB") can be used to design user interfaces visually. IB 创建的接口定义保存在xib文件中。The interface definitions created by IB are saved in .xib files. 可能会为xib文件中的小组件和其他对象提供 "类标识",该标识可以是自定义的用户定义类型。Widgets and other objects in .xib files may be given a "class identity", which can be a custom user-defined type. 这允许您自定义小组件的行为和编写自定义小组件。This allows you to customize the behavior of widgets and to write custom widgets.

这些用户类通常是 UI 控制器类的子类。These user classes are normally subclasses of UI controller classes. 它们具有可连接到接口对象的插座(类似于属性)和操作(类似于事件)。They have outlets (analogous to properties) and actions (analogous to events) that can be connected to interface objects. 在运行时,加载 IB 文件时,会创建对象,并将插座和操作动态连接到各种 UI 对象。At runtime, when the IB file is loaded, the objects are created, and the outlets and actions are connected to the various UI objects dynamically. 定义这些托管类时,必须定义所有操作和插座,使其与 IB 预期的所有操作和插座匹配。When defining these managed classes, you must define all the actions and outlets to match the ones that IB expects. Visual Studio for Mac 使用类似代码隐藏的模型来简化此类。Visual Studio for Mac uses a CodeBehind-like model to simplify this. 这类似于 Xcode 对调整的作用,但代码生成模型和约定更熟悉 .NET 开发人员。This is similar to what Xcode does for Objective-C, but the code generation model and conventions have been tweaked to be more familiar to .NET developers.

在 Visual Studio 中,目前不支持使用xib文件。Working with .xib files is not currently supported in Xamarin.iOS for Visual Studio.

xib 文件和自定义类.xib Files and Custom Classes

还可以在xib文件中定义自定义类型,也可以使用 Cocoa 触控中的现有类型。As well as using existing types from Cocoa Touch, it is possible to define custom types in .xib files. 还可以使用其他xib文件中定义的类型,或者使用纯粹在代码中C#定义的类型。It is also possible to use types that are defined in other .xib files, or defined purely in C# code. 目前 Interface Builder 不知道在xib文件外部定义的类型的详细信息,因此不会列出它们,也不会显示其自定义插座和操作。Currently, Interface Builder is not aware of the details of types defined outside the current .xib file, so it will not list them or show their custom outlets and actions. 删除此限制计划在将来的某个时间进行。Removing this limitation is planned for sometime in the future.

可使用 Interface Builder 的 "类" 选项卡中的 "添加子类" 命令在xib文件中定义自定义类。Custom classes can be defined in a .xib file using the "Add Subclass" command in the "Classes" tab of Interface Builder. 我们将它们称为 "代码隐藏" 类。We refer to these as "CodeBehind" classes. 如果xib文件的项目中有一个 "xib.designer.cs" 对应文件,则 Visual Studio for Mac 会自动使用xib中所有自定义类的分部类定义来填充它。If the .xib file has a ".xib.designer.cs" counterpart file in the project, then Visual Studio for Mac will automatically fill it with partial classes definitions for all the custom classes in the .xib. 我们将这些分部类称为 "设计器类"。We refer to these partial classes as "designer classes".

生成代码Generating Code

对于具有 "生成操作"的任何 {0}xib文件,如果项目中也存在 {0}xib.designer.cs文件,Visual Studio for Mac 将在设计器文件中为它可以在的所有用户类中生成分部类xib文件,其中包含所有操作的插座和分部方法的属性。For any {0}.xib file with a build action of Page, if a {0}.xib.designer.cs file also exists in the project, Visual Studio for Mac will generate partial classes in the designer file for all of the user classes it can find in the .xib file, with properties for the outlets and partial methods for all of the actions. 仅当存在此文件时,才会启用代码生成。Code generation is enabled simply by the presence of this file.

xib文件更改并 Visual Studio for Mac 重新获得焦点时,将自动更新该设计器文件。The designer file is automatically updated when the .xib file changes and Visual Studio for Mac regains focus. 不应手动修改设计器文件,因为下次 Visual Studio for Mac 更新文件时将覆盖更改。The designer file should not be modified manually, as changes will be overwritten next time Visual Studio for Mac updates the file.

注册和命名空间Registration and Namespaces

Visual Studio for Mac 使用设计器文件位置的项目默认命名空间生成设计器类,以使其与普通 .NET 项目 namespacing 保持一致。Visual Studio for Mac generates the designer classes using the project's default namespace for the designer file location, to make it consistent with normal .NET project namespacing. 设计器文件的命名空间由项目的 "默认命名空间" 及其 ".NET 命名策略" 设置驱动。The namespace of designer files is driven by the project's "default namespace" and its ".NET naming policies" settings. 请注意,如果项目的默认命名空间发生更改,MD 将重新生成新命名空间中的类,因此你可能会发现分部类不再匹配。Beware that if your project's default namespace changes, MD will regenerate the classes in the new namespace, so you may find that your partial classes no longer match up.

为了使此类可由目标-C 运行时发现,Visual Studio for Mac 将 [Register (name)] 特性应用于类。To make the class discoverable by the Objective-C runtime, Visual Studio for Mac applies a [Register (name)] attribute to the class. 虽然 Xamarin 会自动注册 NSObject派生的类,但它使用完全限定的 .NET 名称。Although Xamarin.iOS automatically registers NSObject-derived classes, it uses the fully-qualified .NET names. Visual Studio for Mac 应用的特性重写此,以确保每个类都注册到xib文件中使用的名称。The attribute applied by Visual Studio for Mac overrides this to ensure each class is registered with the name used in the .xib file. 如果在 IB 中使用自定义类,而不使用 Visual Studio for Mac 生成设计器文件,则可能需要手动应用此类,以使托管类与预期的目标 C 类名称匹配。If you use custom classes in IB without using Visual Studio for Mac to generate designer files, you may have to apply this manually to make your managed classes match up to the expected Objective-C class names.

不能在多个 xib 中定义类 Classes cannot be defined in more than one .xib, or they will conflict.

非设计器类部件Non-Designer Class Parts

设计器分部类不应按原样使用。Designer partial classes are not intended to be used as-is. 插座是专用的,不指定基类。Outlets are private, and no base class is specified. 预计每个类都将在另一个文件中具有相应的 "非设计器" 类部件,这会设置基类、使用或公开插座,并定义在加载 xib 时实例化类所需的构造函数 .It is expected that each class will have a corresponding "non-designer" class part in another file, which sets the base class, uses or exposes the outlets, and defines constructors that are required to instantiate the class from native code when loading the .xib. Xib模板执行此操作,但对于在xib中定义的任何其他自定义类,必须手动添加非设计器部分。The default .xib templates do this, but for any additional custom classes you define in a .xib, you must add the non-designer part manually.

导致这种情况的原因是需要灵活性。The reason for this is the need for flexibility. 例如,多个代码隐藏类可以为公共托管抽象类提供子类,此类将类划分为通过 IB 划分子类。For example, multiple CodeBehind classes could subclass a common managed abstract class, which subclasses the class to be subclassed by IB.

将其放在 xib.designer.cs 设计器文件 {0} 旁边的 {0}xib.cs文件中。It is conventional to put these in a {0}.xib.cs file beside the {0}.xib.designer.cs designer file.

生成的操作和插座Generated Actions and Outlets

在分部设计器类中,Visual Studio for Mac 生成对应于 IB 中定义的任何连接的插座的属性,以及与任何连接操作对应的分部方法。In the partial designer classes, Visual Studio for Mac generates properties corresponding to any connected outlets defined in IB, and partial methods corresponding to any connected actions.

插座属性Outlet Properties

设计器类包含与自定义类上定义的所有插座相对应的属性。Designer classes contain properties corresponding to all outlets defined on the custom class. 这些是属性的一个事实是,用于启用延迟绑定的 Xamarin 到目标 C 桥的实现细节。The fact that these are properties is an implementation detail of the Xamarin.iOS to Objective C bridge, to enable lazy binding. 应将它们视为等效于私有字段,以便仅用于代码隐藏类。You should consider them to be equivalent to private fields, intended to be used only from the CodeBehind class. 如果要使它们成为公共的,请将访问器属性添加到非设计器类部件,就像对任何其他私有字段一样。If you wish to make them public, add accessor properties to the non-designer class part, as you would for any other private field.

如果将插座属性定义为具有一种类型的 id (等效于 NSObject),则设计器代码生成器当前根据连接到该插座的对象确定最强的可能类型。If outlet properties are defined to have a type of id (equivalent to NSObject) then the designer code generator currently determines the strongest possible type based on objects connected to that outlet, for convenience. 但是,在将来的版本中可能不支持这种情况,因此,建议您在定义自定义类时明确地键入插座。However, this may not be supported in future versions, so it is recommended that you explicitly strongly type the outlets when defining the custom class.

操作属性Action Properties

设计器类包含与自定义类上定义的所有操作对应的分部方法。Designer classes contain partial methods corresponding to all actions defined on the custom class. 这些是没有实现的方法。These are methods without an implementation. 分部方法的目的是双重的:The purpose of the partial methods is twofold:

  1. 如果在非设计器类部件的类体中键入 partial,Visual Studio for Mac 将自动完成所有未实现的分部方法的签名。If you type partial in the class body of the non-designer class part, Visual Studio for Mac will offer to autocomplete the signatures of all non-implemented partial methods.
  2. 分部方法签名具有应用的属性,可将这些属性公开给目标-C 环境,因此,它们可以作为对应的操作进行处理。The partial method signatures have an attribute applied that exposes them to the Objective-C world, so they can get handled as the corresponding action.

如果需要,您可以忽略分部方法,并通过将特性应用于其他方法来实现该操作,也可以让其通过基类。If you wish, you may ignore the partial method, and implement the action by applying the attribute to a different method, or let it fall through to a base class.

如果将操作定义为具有 id 的发送方类型(相当于 NSObject),则设计器代码生成器当前根据连接到该操作的对象确定最强的可能类型。If actions are defined to have a sender type of id (equivalent to NSObject), then the designer code generator currently determines the strongest possible type based on objects connected to that action. 但是,在将来的版本中可能不支持这种情况,因此,建议您在定义自定义类时显式地键入操作。However, this may not be supported in future versions, so it is recommended that you explicitly strongly type the actions when defining the custom class.

请注意,只为C#创建这些分部方法,因为 CodeDOM 不支持分部方法,因此不会为其他语言生成这些方法。Note that these partial methods are created only for C#, because CodeDOM doesn't support partial methods, so they are not generated for other languages.

跨 XIB 类用法Cross-XIB Class Usage

有时,用户希望从多个xib文件引用相同的类(例如,具有选项卡控制器)。Sometimes, users wish to reference the same class from multiple .xib files, for example with tab controllers. 这可以通过显式从另一个xib文件引用类定义来实现,也可以在第二个 . xib中再次定义相同的类名。This can be done by explictly referencing the class definition from another .xib file, or by defining the same class name again in the second .xib.

后一种情况可能会导致 xib 文件单独 Visual Studio for Mac 处理 The latter case can be problematic due to Visual Studio for Mac processing .xib files individually. 它无法自动检测和合并重复的定义,因此,如果在多个设计器文件中定义同一个分部类,则可能会发生冲突,多次应用 Register 特性。It cannot automatically detect and merge duplicate definitions, so you may end up with conflicts applying the Register attribute multiple times when the same partial class is defined in multiple designer files. 最新版本的 Visual Studio for Mac 尝试解决此问题,但它可能不会始终按预期方式工作。Recent versions of Visual Studio for Mac attempt to resolve this, but it may not always work as expected. 将来,这可能会变得不受支持,而 Visual Studio for Mac 会使所有xib文件中的所有类型和项目中的托管代码直接在xib文件中可见。In future this is likely to become unsupported, and instead Visual Studio for Mac will make all types defined in all .xib files and managed code in the project directly visible from all .xib files.

类型解析Type Resolution

IB 中使用的类型为目标-C 类型名称。Types used in IB are Objective-C type names. 这些类型通过使用 Register 特性映射到 CLR 类型。These are mapped to CLR types through the use of Register attributes. 生成插座和操作代码时,Visual Studio for Mac 将为 Xamarin core 所包装的所有目标 C 类型解析相应的 CLR 类型,并完全限定其类型名称。When generating outlet and action code, Visual Studio for Mac will resolve the corresponding CLR types for all Objective-C types wrapped by the Xamarin.iOS core, and fully qualify their type names.

但是,代码生成器目前无法解析用户代码或库中的目标 C 类型名称中的 CLR 类型,因此在这种情况下,它将输出类型名称原义。However, the code generator cannot currently resolve CLR types from Objective-C type names in user code or libraries, so in such cases it outputs the type name verbatim. 这意味着相应的 CLR 类型必须与目标 C 类型具有相同的名称,并且与使用该类型的代码位于同一命名空间中。This means that the corresponding CLR type must have the same name as the Objective-C type and be in the same namespace as the code that's using it. 在代码生成过程中,通过考虑项目中的所有目标 C 类型,计划在将来某个时间修复这种情况。This is planned to be fixed sometime in the future by considering all Objective-C types in the project during code generation.