Xamarin 中的 watchOS 表控件
watchOS WKInterfaceTable
控件比 iOS 控件简单得多,但两者的作用类似。 它创建一个可以采用自定义布局并响应触摸事件的滚动行列表。
添加表
将“表”控件拖放到场景中。 默认情况下,其外观如下(显示单个未指定的行布局):
在“属性”面板的“名称”框中为表命名,以便可以在代码中引用它。
添加行控制器
该表自动包含一行,该行默认由包含“组”控件的行控制器表示。
若要设置行控制器的“类”,请选择“文档大纲”中的行,然后在“属性”面板中键入类名称:
设置行控制器的类后,IDE 将在项目中创建相应的 C# 文件。 将控件(例如标签)拖放到行上,并为其命名,以便可以在代码中引用它们。
创建并填充行
SetNumberOfRows
为每一行创建行控制器类,并使用 Identifier
选择正确的类。 如果为行控制器提供了自定义 Identifier
,请将以下代码片段中的 default 更改为你使用的标识符。 每一行的 RowController
是在调用 SetNumberOfRows
和显示表时创建的。
myTable.SetNumberOfRows ((nint)rows.Count, "default");
// loads row controller by identifier
重要
表行不像在 iOS 中那样被虚拟化。 请尽量限制行数(Apple 建议少于 20 个)。
创建行后,需要填充每个单元格(就像 iOS 中的 GetCell
所做的那样)。 此代码片段更新每行中的标签:
for (var i = 0; i < rows.Count; i++) {
var elementRow = (RowController)myTable.GetRowController (i);
elementRow.myRowLabel.SetText (rows [i]);
}
重要
使用 SetNumberOfRows
,然后使用 GetRowController
进行循环访问会导致将整个表发送到手表。 在表的后续视图中,如果需要添加或删除特定行,请使用 InsertRowsAt
和 RemoveRowsAt
以获得更好的性能。
响应点击
可以通过两种不同的方式响应行选择:
- 在接口控制器上实现
DidSelectRow
方法,或者 - 如果你希望行选择操作打开另一个场景,请在情节提要上创建一个 Segue 并实现
GetContextForSegue
。
DidSelectRow
若要以编程方式处理行选择,请实现 DidSelectRow
方法。 若要打开新场景,请使用 PushController
并传递场景的标识符以及要使用的数据上下文:
public override void DidSelectRow (WKInterfaceTable table, nint rowIndex)
{
var rowData = rows [(int)rowIndex];
Console.WriteLine ("Row selected:" + rowData);
// if selection should open a new scene
PushController ("secondInterface", rows[(int)rowIndex]);
}
GetContextForSegue
将情节提要上的 Segue 从表行拖放到另一个场景(拖动时按住 Ctrl 键)。
请务必选择 Segue 并在“属性”面板中为其指定一个标识符(例如以下示例中的 secondLevel
)。
在接口控制器中,实现 GetContextForSegue
方法并返回应提供给 Segue 呈现的场景的数据上下文。
public override NSObject GetContextForSegue (string segueIdentifier, WKInterfaceTable table, nint rowIndex)
{
if (segueIdentifier == "secondLevel") {
return new NSString (rows[(int)rowIndex]);
}
return null;
}
此数据通过其 Awake
方法传递给目标情节提要场景。
多行类型
默认情况下,表控件具有可设计的单行类型。 若要添加更多行“模板”,请使用“属性”面板中的“行”框来创建更多行控制器:
将“行数”属性设置为 3 会创建额外的行占位符,供你将控件拖入其中。 对于每一行,请在“属性”面板中设置类名称,以确保创建行控制器类。
若要使用不同的行类型填充表,请使用 SetRowTypes
方法指定表中每行要使用的行控制器类型。 使用行的标识符指定每行应使用哪个行控制器。
此数组中的元素数量应与表中预期的行数匹配:
myTable.SetRowTypes (new [] {"type1", "default", "default", "type2", "default"});
使用多个行控制器填充表时,需要在填充 UI 时跟踪预期的类型:
for (var i = 0; i < rows.Count; i++) {
if (i == 0) {
var elementRow = (Type1RowController)myTable.GetRowController (i);
// populate UI controls
} else if (i == 3) {
var elementRow = (Type2RowController)myTable.GetRowController (i);
// populate UI controls
} else {
var elementRow = (DefaultRowController)myTable.GetRowController (i);
// populate UI controls
}
}
垂直详细信息分页
watchOS 3 为表引入了一项新功能:能够滚动浏览与每行相关的详细信息页,而无需返回表并选择另一行。 可以通过上下滑动或使用 Digital Crown 来滚动详细信息屏幕。
重要
目前只能通过在 Xcode Interface Builder 中编辑情节提要来使用此功能。
若要启用此功能,请选择设计图面上的 WKInterfaceTable
,并勾选“垂直详细信息分页”选项:
如 Apple 所解释的那样,表导航必须使用 Segues 才能使分页功能发挥作用。 重写任何使用 PushController
的现有代码以改用 Segue。
附录:行控制器代码示例
在设计器中创建行控制器时,IDE 将自动创建两个代码文件。 下面显示了这些生成的文件中的代码以供参考。
第一个文件根据类命名,例如 RowController.cs,如下所示:
using System;
using Foundation;
namespace WatchTablesExtension
{
public partial class RowController : NSObject
{
public RowController ()
{
}
}
}
另一个 .designer.cs 文件是一个分部类定义,其中包含在设计器图面上创建的输出口和操作,例如此示例包含一个 WKInterfaceLabel
控件:
using Foundation;
using System;
using System.CodeDom.Compiler;
using UIKit;
namespace WatchTables.OnWatchExtension
{
[Register ("RowController")]
partial class RowController
{
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
public WatchKit.WKInterfaceLabel MyLabel { get; set; }
void ReleaseDesignerOutlets ()
{
if (MyLabel != null) {
MyLabel.Dispose ();
MyLabel = null;
}
}
}
}
然后可以在代码中引用此处声明的输出口和操作 - 但不要直接编辑 .designer.cs 文件。