ios - Apple Watch Table 上的行选择崩溃

标签 ios xamarin xamarin.ios watchkit

我正在使用 Xamarin 开发 Apple Watch 应用。我添加了一个表 (WKInterfaceTable) 并使用代码隐藏填充它。但是当我点击一行时,应用程序立即崩溃。

为了做到这一点,我实际上手动编辑了 Storyboard XML 文件,因为它不能通过简单地在 Storyboard上拖放表格来工作。这是 XML:

<?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>

我在 XML 中有什么问题吗?
InterfaceController 的代码:
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]);
        }
    }
}
InterfaceController.designer.cs 的代码:
[Register("InterfaceController")]
partial class InterfaceController
{
    [Outlet]
    public WKInterfaceTable InterfaceTable { get; set; }

    void ReleaseDesignerOutlets()
    {
        if (InterfaceTable != null)
        {
            InterfaceTable.Dispose();
            InterfaceTable = null;
        }
    }
}
FavoriteRowController 的代码:
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);
    }
}
FavoriteRowController.designer.cs 的代码:
[Register("FavoriteRowController")]
partial class FavoriteRowController
{
    [Outlet]
    public WKInterfaceLabel RowLabel { get; set; }

    void ReleaseDesignerOutlets()
    {
    }
}

应用程序输出中的崩溃异常:
2016-11-03 10:10:58.780 MyAppWatchExtension[16255:474000] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<FavoriteRowController 0x799ec7e0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key InterfaceTable.' *** First throw call stack: ( 0 CoreFoundation 0x00383a22 __exceptionPreprocess + 194 1 libobjc.A.dylib 0x059a0e76 objc_exception_throw + 52 2 CoreFoundation 0x00383951 -[NSException raise] + 17 3 Foundation 0x013c5732 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 238 4 Foundation 0x012eac53 _NSGetUsingKeyValueGetter + 146 5 Foundation 0x012eab3b -[NSObject(NSKeyValueCoding) valueForKey:] + 282 6 WatchKit 0x04b06c16 __58-[SPRemoteInterface handlePlistDictionary:fromIdentifier:]_block_invoke.882 + 39 7 libdispatch.dylib 0x06252c4f _dispatch_call_block_and_release + 15 8 libdispatch.dylib 0x0627550f _dispatch_client_callout + 14 9 libdispatch.dylib 0x0625be31 _dispatch_main_queue_callback_4CF + 1031 10 CoreFoundation 0x00343e7e __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14 11 CoreFoundation 0x00306dcf __CFRunLoopRun + 2319 12 CoreFoundation 0x0030624b CFRunLoopRunSpecific + 395 13 CoreFoundation 0x003060ab CFRunLoopRunInMode + 123 14 Foundation 0x012c5192 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 308 15 Foundation 0x012c504f -[NSRunLoop(NSRunLoop) run] + 69 16 libxpc.dylib 0x0656d8a5 _xpc_objc_main + 476 17 libxpc.dylib 0x06570175 xpc_main + 215 18 Foundation 0x01323880 +[NSXPCListener serviceListener] + 0 19 PlugInKit 0x111556b6 -[PKService run] + 954 20 WatchKit 0x04b43108 main + 148 21 libxamarin-debug.dylib 0x0584fb33 xamarin_main + 3475 22 TycoMobilePassUIiOSWatchExtension 0x001055bc xamarin_watchextension_main + 124 23 libdyld.dylib 0x062ae85d start + 1 24 ??? 0x00000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException

最佳答案

如果在选择项目而不是在显示表格时发生崩溃,那么我会假设它与行选择代码有关,并从那里开始。

根据您要执行的操作,这里有两个选项:

DidSelectRow

选择行时使用,并且要操纵一些数据或移动到另一个 View 。

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 时使用,以便为正在使用的下一个界面 Controller 设置上下文。
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,
    };
}

在设置上下文后移动到另一个 View 时,您需要转换上下文对象并检查它是否属于您要查找的类型:
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
    }
}

如果您可以发布您的接口(interface) Controller 代码或行选择代码,那么我可能会提供更多帮助。此外,如果您在应用程序输出中遇到任何可能有帮助的错误。

==================================================== ==========================
更新

好的,从您的错误输出中我会说它是 FavoriteRowController那是缺少 Storyboard中的 socket 或错误的类(class)。

this class is not key value coding-compliant for the key InterfaceTable.'



当您缺少导出或删除导出但未删除 Storyboard 中的链接时,这是一个常见错误。

RowControllers 不需要是 InterfaceControllers 所以我会像这样设置它:
FavoriteRowController 的代码:
using Foundation;

namespace WatchConnectivity.OnWatchExtension
{
    public partial class FavoriteRowController : NSObject
    {
        protected FavoriteRowController()
        {
        }
    }
}
FavoriteRowController.designer.cs 的代码:
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;
            }
        }
    }
}

检查此sample

关于ios - Apple Watch Table 上的行选择崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40390548/

相关文章:

ios - Xamarin 通知服务扩展问题

ios - 在 iOS 的表格 View 单元格中更改披露指示器附件 View 的颜色/ View 的最佳方法是什么?

ios - MKReverseGeocoder不返回SubAdministrativeArea

c# - "hill climbing, change max number of threads 5"在我加载数据时以 xamarin 形式在我的 android 设备上调试时

android - 使用可本地化的格式字符串进行数据绑定(bind)

ios - Monotouch.Dialog IOS 6 Split View旋转问题

objective-c - 全屏 : AVPlayerLayer is not resized when resizing its parent view

ios - iOS 13 中 Controller 呈现模态时的 UINavigationBar 高度

iphone - 用 NSMutableArray 填充 UITableview

c# - 有没有办法让通知在被视为横幅后出现在锁定屏幕上? iOS12