问题
I know this question has been asked a million times but I'm getting the error trying to follow along with Stuart Lodge's tutorials "N+1 days of MvvmCross", N=11, CollectionView. I'm not following along 100% as I've got another project that I'm editing while watching the tutorials so I'm sure I've just missed something. Here is the full error message:
Foundation.MonoTouchException: Objective-C exception thrown.
Name: NSUnknownKeyException Reason: [<NSObject 0x796c2460>
setValue:forUndefinedKey:]: this class is not key value
coding-compliant for the key MyLabel.
There appears to be a valid outlet for the auto-generate partial class for TestItemView
I don't believe this is a case of adding a control to the xib, then removing it, so that there is a stranded connection. This happens when I delete the xib and start all over again. I have a "FirstView : MvxCollectionViewController" and for the cells I have a "TestItemView : MvxCollectionViewCell" which is a stand-in for the "KittenCollectionCell". I will give the source code for FirstView, TestItemView, and the TestItemView.xib below.
FirstView:
using System.Drawing;
using MvvmCross.Binding.BindingContext;
using MvvmCross.iOS.Views;
using Foundation;
using MvvmCross.Binding.iOS.Views;
using UIKit;
namespace FirstDemo.Core.iOS.Views
{
[Register("FirstView")]
public class FirstView : MvxCollectionViewController
{
private bool _isInitialized = false;
public FirstView() : base(new UICollectionViewFlowLayout() {
ItemSize = new SizeF(240, 400),
ScrollDirection = UICollectionViewScrollDirection.Horizontal
})
{
_isInitialized = true;
ViewDidLoad();
}
public sealed override void ViewDidLoad()
{
if (!_isInitialized)
return;
base.ViewDidLoad();
//var source = new MvxStandardTableViewSource(TestItemsTableView, "TitleText Name;");
//TestItemsTableView.Source = source;
CollectionView.RegisterNibForCell(TestItemView.Nib, TestItemView.Key);
var source = new MvxCollectionViewSource(CollectionView, TestItemView.Key);
CollectionView.Source = source;
var set = this.CreateBindingSet<FirstView, Core.ViewModels.FirstViewModel>();
set.Bind(source).To(vm => vm.TestItemViewModels);
set.Apply();
CollectionView.ReloadData();
}
}
}
Here is my hand-coded partial for TestItemView:
using System;
using FirstDemo.Core.ViewModels;
using Foundation;
using MvvmCross.Binding.BindingContext;
using MvvmCross.Binding.iOS.Views;
using UIKit;
namespace FirstDemo.Core.iOS
{
public partial class TestItemView : MvxCollectionViewCell
{
public static readonly UINib Nib = UINib.FromName("TestItemView", NSBundle.MainBundle);
public static readonly NSString Key = new NSString("TestItemView");
public TestItemView(IntPtr handle)
: base(string.Empty /* TODO - this isn't really needed - mvx bug */, handle)
{
this.DelayBind(() =>
{
var set = this.CreateBindingSet<TestItemView, TestItemViewModel>();
set.Bind(MyLabel).To(testItem => testItem.Name);
set.Apply();
});
}
public static TestItemView Create()
{
return (TestItemView)Nib.Instantiate(null, null)[0];
}
}
}
Here is the auto-generated partial:
// WARNING
//
// This file has been generated automatically by Xamarin Studio from the outlets and
// actions declared in your storyboard file.
// Manual changes to this file will not be maintained.
//
using Foundation;
using System;
using System.CodeDom.Compiler;
using UIKit;
namespace FirstDemo.Core.iOS
{
[Register ("TestItemView")]
partial class TestItemView
{
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UILabel MyLabel { get; set; }
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIView TestItemInfo { get; set; }
void ReleaseDesignerOutlets ()
{
if (MyLabel != null) {
MyLabel.Dispose ();
MyLabel = null;
}
if (TestItemInfo != null) {
TestItemInfo.Dispose ();
TestItemInfo = null;
}
}
}
}
And finally, the notorious xib for TestItemView:
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"><dependencies><plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/></dependencies><objects><placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="TestItemView"><connections><outlet property="MyLabel" destination="28" id="name-outlet-28"/><outlet property="TestItemInfo" destination="1" id="name-outlet-1"/></connections></placeholder><placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/><view contentMode="scaleToFill" id="1"><rect key="frame" x="0.0" y="0.0" width="600" height="600"/><autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/><color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/><subviews><label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Label" lineBreakMode="tailTruncation" minimumFontSize="10" id="28" translatesAutoresizingMaskIntoConstraints="NO" fixedFrame="YES"><rect key="frame" x="235" y="172" width="42" height="21"/><color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/><fontDescription key="fontDescription" type="system" pointSize="17"/><color key="textColor" cocoaTouchSystemColor="darkTextColor"/><nil key="highlightedColor"/></label></subviews><userDefinedRuntimeAttributes><userDefinedRuntimeAttribute keyPath="accessibilityIdentifier" type="string" value="MyTestItem"/></userDefinedRuntimeAttributes></view></objects></document>
If anyone has a clue, I'd appreciate the help because I'm at a complete loss.
Thanks!
回答1:
I am not familier with the swift approach. But in objective-c, you have to manually add outlet object from XIB to code. And when your XIB's view is linked to some older view's address this error will appear. So in objective-c we used to do the below steps.
- open you XIB
- search for the label with name MyLabel
- verify the connection(which object it is linked to)
- if needed, remove the outlet linking and add that once again.
来源:https://stackoverflow.com/questions/37364361/mvvmcross-xamarin-this-class-is-not-key-value-coding-compliant-for-the-key