Ios 选定行上的Apple Watch表崩溃
我正在使用Xamarin开发一个Apple Watch应用程序。我添加了一个表(WKInterfaceTable)并用代码填充它。但当我点击一行时,应用程序立即崩溃 为了做到这一点,我实际上手动编辑了序列图像板XML文件,因为简单地在序列图像板上拖放一个表是行不通的。以下是XML:Ios 选定行上的Apple Watch表崩溃,ios,xamarin,xamarin.ios,watchkit,Ios,Xamarin,Xamarin.ios,Watchkit,我正在使用Xamarin开发一个Apple Watch应用程序。我添加了一个表(WKInterfaceTable)并用代码填充它。但当我点击一行时,应用程序立即崩溃 为了做到这一点,我实际上手动编辑了序列图像板XML文件,因为简单地在序列图像板上拖放一个表是行不通的。以下是XML: <?xml version="1.0" encoding="UTF-8" standalone="no"?> <document type="com.apple.InterfaceBuilder.W
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="6221" systemVersion="14A389" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="AgC-eL-Hgc">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6213"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="3734"/>
</dependencies>
<scenes>
<!--Interface Controller-->
<scene sceneID="aou-V4-d1y">
<objects>
<controller id="AgC-eL-Hgc" title="Favorites" customClass="InterfaceController" customModuleProvider="">
<items>
<table alignment="left" id="nXC-Mh-TYy">
<items>
<tableRow identifier="default" id="zJA-dk-zIT" customClass="FavoriteRowController">
<group key="rootItem" width="1" height="40" alignment="left" spacing="6" id="ASs-9x-fCK">
<items>
<imageView width="35" height="35" alignment="left" verticalAlignment="center" image="Door" id="rac-gq-1kM"/>
<label alignment="left" verticalAlignment="center" text="Location" id="jkO-KQ-vGr"/>
</items>
<color key="backgroundColor" red="0.93625843524932861" green="0.94465947151184082" blue="0.98500943183898926" alpha="0.14000000000000001" colorSpace="custom" customColorSpace="sRGB"/>
<edgeInsets key="margins" left="2" right="2" top="2" bottom="2"/>
</group>
<connections>
<outlet property="RowLabel" destination="jkO-KQ-vGr" id="Hcb-P2-F5Q"/>
</connections>
</tableRow>
</items>
</table>
</items>
<connections>
<outlet property="InterfaceTable" destination="nXC-Mh-TYy" id="4YS-uT-eWw"/>
</connections>
</controller>
</objects>
<point key="canvasLocation" x="0.0" y="0.0"/>
</scene>
</scenes>
InterfaceController.designer.cs的代码
:
[Register("InterfaceController")]
partial class InterfaceController
{
[Outlet]
public WKInterfaceTable InterfaceTable { get; set; }
void ReleaseDesignerOutlets()
{
if (InterfaceTable != null)
{
InterfaceTable.Dispose();
InterfaceTable = null;
}
}
}
[Register("FavoriteRowController")]
partial class FavoriteRowController
{
[Outlet]
public WKInterfaceLabel RowLabel { get; set; }
void ReleaseDesignerOutlets()
{
}
}
using Foundation;
using System.CodeDom.Compiler;
namespace WatchConnectivity.OnWatchExtension
{
[Register ("FavoriteRowController")]
partial class FavoriteRowController
{
[Outlet]
public WatchKit.WKInterfaceLabel RowLabel { get; set; }
void ReleaseDesignerOutlets ()
{
if (RowLabel != null) {
RowLabel.Dispose ();
RowLabel = null;
}
}
}
}
FavoriteRowController的代码
:
public partial class InterfaceController : WKInterfaceController
{
protected InterfaceController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override void Awake(NSObject context)
{
base.Awake(context);
this.LoadTableData();
// Configure interface objects here.
Console.WriteLine("{0} awake with context", this);
}
public override void WillActivate()
{
// This method is called when the watch view controller is about to be visible to the user.
Console.WriteLine("{0} will activate", this);
}
public override void DidDeactivate()
{
// This method is called when the watch view controller is no longer visible to the user.
Console.WriteLine("{0} did deactivate", this);
}
private void LoadTableData()
{
var cityNames = new[] { "r1", "r2", "r3", "r4", "r5" };
InterfaceTable.SetNumberOfRows(cityNames.Length, "default");
for (var i = 0; i < cityNames.Length; i++)
{
var row = (FavoriteRowController)InterfaceTable.GetRowController(i);
row.RowLabel.SetText(cityNames[i]);
}
}
}
public partial class FavoriteRowController : WKInterfaceController
{
protected FavoriteRowController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override void Awake(NSObject context)
{
base.Awake(context);
// Configure interface objects here.
Console.WriteLine("{0} awake with context", this);
}
public override void WillActivate()
{
// This method is called when the watch view controller is about to be visible to the user.
Console.WriteLine("{0} will activate", this);
}
public override void DidDeactivate()
{
// This method is called when the watch view controller is no longer visible to the user.
Console.WriteLine("{0} did deactivate", this);
}
}
using Foundation;
namespace WatchConnectivity.OnWatchExtension
{
public partial class FavoriteRowController : NSObject
{
protected FavoriteRowController()
{
}
}
}
FavoriteRowController.designer.cs的代码
:
[Register("InterfaceController")]
partial class InterfaceController
{
[Outlet]
public WKInterfaceTable InterfaceTable { get; set; }
void ReleaseDesignerOutlets()
{
if (InterfaceTable != null)
{
InterfaceTable.Dispose();
InterfaceTable = null;
}
}
}
[Register("FavoriteRowController")]
partial class FavoriteRowController
{
[Outlet]
public WKInterfaceLabel RowLabel { get; set; }
void ReleaseDesignerOutlets()
{
}
}
using Foundation;
using System.CodeDom.Compiler;
namespace WatchConnectivity.OnWatchExtension
{
[Register ("FavoriteRowController")]
partial class FavoriteRowController
{
[Outlet]
public WatchKit.WKInterfaceLabel RowLabel { get; set; }
void ReleaseDesignerOutlets ()
{
if (RowLabel != null) {
RowLabel.Dispose ();
RowLabel = null;
}
}
}
}
应用程序输出中的崩溃异常:
2016-11-03 10:10:58.780 MyAppWatchExtension[16255:474000]***由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[valueForUndefinedKey:]:此类不符合密钥接口表的键值编码。”
***第一次抛出调用堆栈:
(
0 CoreFoundation 0x00383a22例外预处理+194
1 libobjc.A.dylib 0x059a0e76 objc_异常_抛出+52
2芯基础0x00383951-[N异常升高]+17
3基金会0x013C532-[ NSKORKS(NSKEY ValueCudid)ValueFunDealEdKEY:] + 238
4基金会0x012EAC53、NGETUSENG KEY ValueGETER + 146
5基金会0x012EAB3B-[ NStObjs](NSKEY ValueCudid)ValueFoiKy::+ 282
6 WatchKit 0x04b06c16 _58-[SPRemoteInterface HandleListDictionary:fromIdentifier:][u block_invoke.882+39
7 libdispatch.dylib 0x06252c4f调度调用块和释放+15
8 libdispatch.dylib 0x0627550f_dispatch_client_callout+14
9 libdispatch.dylib 0x0625be31_dispatch_main_queue_callback_4CF+1031
10 CoreFoundation 0x00343e7e\uuuu CFRUNLOOP\u正在为\u主\u调度\u队列\uuuuu+14提供服务
11 CoreFoundation 0x00306dcf\uuu CFRunLoopRun+2319
12 CoreFoundation 0x0030624b CFRunLoopRunSpecific+395
13 CoreFoundation 0x003060ab CFRunLoopRunInMode+123
14基金会0x012C5192-[ NSRunCURLL(NSRunLob)RunMy:BeFueDATE::+ 308
15基金会0x012C504F- [ NSRunLoCon(NSRunCoul)运行] + 69
16 libxpc.dylib 0x0656d8a5\u xpc\u objc\u main+476
17 libxpc.dylib 0x06570175 xpc_main+215
18基金会0x01323 880+ [ NSXPCListener serviceListener ] + 0
19 PlugInKit 0x111556b6-[PKService run]+954
20手表套件0x04b43108主+148
21 libxamarin-debug.dylib 0x0584fb33 xamarin_main+3475
22 TycomobilePassuiiosWatch分机0x001055bc xamarin_Watch分机+124
23 libdyld.dylib 0x062ae85d开始+1
24°?0x00000001 0x0+1
)
libc++abi.dylib:以NSException类型的未捕获异常终止
如果崩溃发生在选择项时,而不是在显示表时,那么我假设这与行选择代码有关,并从那里开始
根据您尝试执行的操作,这里有两个选项:
DidSelectRow
选中行并希望操作某些数据或移动到其他视图时使用
public override async void DidSelectRow(WKInterfaceTable table, nint rowIndex)
{
var contextForNextInterfaceController = rows[(int)rowIndex]; // this depends how you have set up the table.
Console.WriteLine($"Row selected: {rowData}");
PushController("TheNextInterFaceController", contextForNextInterfaceController);
}
GetContextForSegue
在iOS Designer或Xcode中设置segue时使用,以便为正在使用的下一个接口控制器设置上下文
public override NSObject GetContextForSegue(string segueIdentifier, WKInterfaceTable table, nint rowIndex)
{
// Can check segueIdentifier if using more segues
return new ContextForNextInterfaceController() // This needs to sub class NSObject
{
model = modelForNextInterfaceController,
};
}
设置上下文后移动到另一个视图时,您将使用文本强制转换上下文对象,并检查它是否属于您要查找的类型:
public override void Awake(NSObject context)
{
base.Awake(context);
Console.WriteLine("{0} awake with context", this);
var currentContext = context as ContextForNextInterfaceController;
if (currentContext != null)
{
// Do stuff with context
}
}
如果您可以发布界面控制器代码或行选择代码,那么我可能可以提供更多帮助。此外,如果您在应用程序输出中遇到任何错误,这也会有所帮助
===========================================================================
更新
好的,从您的错误输出中,我会说是FavoriteRowController
缺少插座或故事板中设置了错误的类
此类不符合key InterfaceTable的键值编码。'
当您缺少插座或删除了插座但未删除情节提要中的链接时,这是一个常见错误
RowController不需要是InterfaceController,所以我会这样设置:
FavoriteRowController的代码
:
public partial class InterfaceController : WKInterfaceController
{
protected InterfaceController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override void Awake(NSObject context)
{
base.Awake(context);
this.LoadTableData();
// Configure interface objects here.
Console.WriteLine("{0} awake with context", this);
}
public override void WillActivate()
{
// This method is called when the watch view controller is about to be visible to the user.
Console.WriteLine("{0} will activate", this);
}
public override void DidDeactivate()
{
// This method is called when the watch view controller is no longer visible to the user.
Console.WriteLine("{0} did deactivate", this);
}
private void LoadTableData()
{
var cityNames = new[] { "r1", "r2", "r3", "r4", "r5" };
InterfaceTable.SetNumberOfRows(cityNames.Length, "default");
for (var i = 0; i < cityNames.Length; i++)
{
var row = (FavoriteRowController)InterfaceTable.GetRowController(i);
row.RowLabel.SetText(cityNames[i]);
}
}
}
public partial class FavoriteRowController : WKInterfaceController
{
protected FavoriteRowController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override void Awake(NSObject context)
{
base.Awake(context);
// Configure interface objects here.
Console.WriteLine("{0} awake with context", this);
}
public override void WillActivate()
{
// This method is called when the watch view controller is about to be visible to the user.
Console.WriteLine("{0} will activate", this);
}
public override void DidDeactivate()
{
// This method is called when the watch view controller is no longer visible to the user.
Console.WriteLine("{0} did deactivate", this);
}
}
using Foundation;
namespace WatchConnectivity.OnWatchExtension
{
public partial class FavoriteRowController : NSObject
{
protected FavoriteRowController()
{
}
}
}
FavoriteRowController.designer.cs的代码
:
[Register("InterfaceController")]
partial class InterfaceController
{
[Outlet]
public WKInterfaceTable InterfaceTable { get; set; }
void ReleaseDesignerOutlets()
{
if (InterfaceTable != null)
{
InterfaceTable.Dispose();
InterfaceTable = null;
}
}
}
[Register("FavoriteRowController")]
partial class FavoriteRowController
{
[Outlet]
public WKInterfaceLabel RowLabel { get; set; }
void ReleaseDesignerOutlets()
{
}
}
using Foundation;
using System.CodeDom.Compiler;
namespace WatchConnectivity.OnWatchExtension
{
[Register ("FavoriteRowController")]
partial class FavoriteRowController
{
[Outlet]
public WatchKit.WKInterfaceLabel RowLabel { get; set; }
void ReleaseDesignerOutlets ()
{
if (RowLabel != null) {
RowLabel.Dispose ();
RowLabel = null;
}
}
}
}
检查这个我修复了它,这是因为我的RowController类应该派生自
NSObject
,而不是WKInterfaceController
如果它加载了表,那么它可能不是脚本。您是否也可以添加您在选择表行时使用的代码?您使用的是xamarin studio还是VS?另外,我不会手动编辑故事板文件,除非它是一个小更改(一个简单的值)。它不像Android,ID是生成的,很容易搞乱。