【问题标题】:How do I get custom UIView XIB to show in the Xamarin iOS Designer?如何让自定义 UIView XIB 显示在 Xamarin iOS 设计器中?
【发布时间】:2017-06-30 20:52:41
【问题描述】:

我为 Xamarin.iOS 构建了一个自定义控件。它只是一个带有标签的开关。您可以按控件上的任意位置来切换开关。

开关效果很好,我可以在运行时看到它,但我希望不要让自定义控件的未来用户感到困惑。该控件只不过是一个空白框或一个红色框,在设计时有一个例外,我似乎无法弄清楚如何让它显示出来。该文档没有提到使用 XIB 文件来设计控件的视觉元素。

我做了一点挖掘,发现了一个关于这个问题的objective-c问题:Failed to render instance of ClassName: The agent threw an exception loading nib in bundle

不幸的是,我找不到与上述代码等效的 C#。需要做什么才能让我的控件在 Xamarin iOS 设计器的设计时显示?

下面是代码:

/// <summary>
/// Labeled switch is a custom control
/// </summary>
[DesignTimeVisible(true)]
public partial class LabeledSwitch : UIView, IComponent
{
    public LabeledSwitch (IntPtr handle) : base (handle)
    {
        Initialize(CGRect.Empty);
    }

    public LabeledSwitch (CGRect frame) : base(frame)
    {
        Initialize(frame);
    }

    #region IComponent Impl

    public ISite Site { get ; set; }
    public event EventHandler Disposed;

    #endregion
    [Export("Text"), Browsable(true)]
    public string Text { get; set; }

    public UISwitch LabelSwitch { get; set; }

    public override void AwakeFromNib()
    {
        base.AwakeFromNib();
        Initialize(CGRect.Empty);
    }

    private void Initialize(CGRect frame)
    {

        if ((Site != null) && Site.DesignMode)
        {
            // Bundle resources aren't available in DesignMode?
            // Thought this might work but it does nothing
            var bundle = NSBundle.FromIdentifier("LabeledSwitch");
            bundle.LoadNib("LabeledSwitch", this, null);
            return;
        }

        BackgroundColor = UIColor.Clear;
        NSBundle.MainBundle.LoadNib("LabeledSwitch", this, null);

        AddSubview(RootView);

        SetTouchBehaviorOfLabeledSwitch();

        Frame = Bounds;
        RootView.Frame = Bounds;

        Label.Text = Text;

        LabelSwitch = Switch;

        HeightAnchor.ConstraintEqualTo(40f);
        RefreshSwitchBackground();
    }

    private void SetTouchBehaviorOfLabeledSwitch()
    {
        BackgroundView.TouchUpInside += TouchedLabeledSwitch;
    }

    private void TouchedLabeledSwitch(object sender, EventArgs e)
    {
        Switch.SetState(!Switch.On, true);
        RefreshSwitchBackground();
    }

    private void RefreshSwitchBackground()
    {
        if (Switch.On)
        {
            BackgroundView.BackgroundColor = UIColor.FromRGB(191, 249, 191);
            return;
        }
        BackgroundView.BackgroundColor = UIColor.FromRGB(239, 239, 244);
    }
}

这里是 xib:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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="LabeledSwitch">
            <connections>
                <outlet property="BackgroundView" destination="4" id="name-outlet-4"/>
                <outlet property="Switch" destination="5" id="name-outlet-5"/>
                <outlet property="Label" destination="6" id="name-outlet-6"/>
                <outlet property="RootView" 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" customColorSpace="calibratedWhite" colorSpace="calibratedWhite" white="0" alpha="0"/>
            <subviews>
                <view contentMode="scaleToFill" id="4" translatesAutoresizingMaskIntoConstraints="NO" customClass="UIControl">
                    <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                    <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
                    <userDefinedRuntimeAttributes>
                        <userDefinedRuntimeAttribute keyPath="layer.cornerRadius" type="number">
                            <real key="value" value="5"/>
                        </userDefinedRuntimeAttribute>
                    </userDefinedRuntimeAttributes>
                    <subviews>
                        <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" id="5" translatesAutoresizingMaskIntoConstraints="NO" userInteractionEnabled="NO">
                            <rect key="frame" x="533" y="285" width="51" height="31"/>
                            <constraints>
                                <constraint id="16" firstItem="5" firstAttribute="height" constant="31"/>
                                <constraint id="17" firstItem="5" firstAttribute="width" constant="49"/>
                            </constraints>
                            <accessibility key="accessibilityConfiguration">
                                <accessibilityTraits key="traits" button="YES" notEnabled="YES"/>
                            </accessibility>
                            <connections>
                                <action selector="HandleSwitchStateChanged:" destination="-1" id="20" eventType="valueChanged"/>
                            </connections>
                        </switch>
                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="6" translatesAutoresizingMaskIntoConstraints="NO">
                            <rect key="frame" x="16" y="290" width="42" height="21"/>
                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
                            <color key="textColor" colorSpace="calibratedWhite" white="0.333333333333333" alpha="1"/>
                            <nil key="highlightedColor"/>
                            <constraints>
                                <constraint id="8" firstItem="6" firstAttribute="height" constant="21"/>
                            </constraints>
                            <accessibility key="accessibilityConfiguration">
                                <accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
                            </accessibility>
                        </label>
                    </subviews>
                    <constraints>
                        <constraint id="7" firstItem="6" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="16"/>
                        <constraint id="9" firstItem="6" firstAttribute="centerY" secondItem="4" secondAttribute="centerY"/>
                        <constraint id="14" firstItem="4" firstAttribute="trailing" secondItem="5" secondAttribute="trailing" constant="18"/>
                        <constraint id="15" firstItem="5" firstAttribute="centerY" secondItem="4" secondAttribute="centerY"/>
                    </constraints>
                </view>
            </subviews>
            <constraints>
                <constraint id="10" firstItem="4" firstAttribute="top" secondItem="1" secondAttribute="top"/>
                <constraint id="11" firstItem="4" firstAttribute="leading" secondItem="1" secondAttribute="leading"/>
                <constraint id="12" firstItem="4" firstAttribute="bottom" secondItem="1" secondAttribute="bottom"/>
                <constraint id="13" firstItem="4" firstAttribute="trailing" secondItem="1" secondAttribute="trailing"/>
            </constraints>
        </view>
    </objects>
    <resources>
        <!-- ... Image tags are here-->
    </resources>
</document>

【问题讨论】:

    标签: c# ios xamarin.ios


    【解决方案1】:

    我自己不得不搞砸这个,Xamarin 并不总是完美的,我发现重新注册课程有时会迫使它出现在工具箱和情节提要中。 (虽然我不相信你应该这样做)。此代码将位于您的类上方和您的命名空间内。

    [DesignTimeVisible(true), Category("Controls")]
    [Register("MyView")]
    

    如果您对如何格式化和创建控件有任何疑虑,请访问很棒的 github Here。这些都是开源用户和 xamarin 贡献的控件,非常好地组合在一起,如果您查看其中的一些类,可以为您提供有关如何在 Xamarin 中正确创建设计时可查看控件的缺失信息。

    【讨论】:

    • 控件已经出现在工具箱中,我可以在storyboards和xibs中拖放/使用它。问题是该控件仅显示一个透明框或一个红色框,并引用了 Objective-c 文章中的异常。我已经附上了截图
    猜你喜欢
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 2015-04-17
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多