I built a custom control for Xamarin.iOS. It's just a switch with a label. You can press anywhere on the control to toggle the switch.
The switch works great and I can see it at Runtime, but I was hoping not to confuse future users of the custom control. The control is nothing but a blank box or a red box with an exception at design time, and I can't seem to figure out how to get it to show up. The documentation makes no mention of using a XIB file to design the visual elements of your control.
I did a little digging and found an objective-c question about this problem: Failed to render instance of ClassName: The agent threw an exception loading nib in bundle
Unfortunately I can't find a C# equivalent of the code mentioned. What needs to be done to get my control to show at Design Time in the Xamarin iOS designer?
Here's the code behind:
/// <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);
}
}
And here's the 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>