Reputation: 5989
I have created a custom view (new class derived from UIView). This view is meant to use as a header in my iOS application and basically contains two labels called "Title" and "SubTitle". I have created two matching string properties which can be used to set the text of the "Title" and "SubTitle" labels.
My question is, what's the best place to assign the string values supplied to the properties (let's say using binding with MvvmCross or just simply the iOS designer) to the .text property of the labels?
I know it will work when I override the Draw(CGRect rect)
method and assign the values in here (and call the SetNeedsDisplay()
method when the properties values change). However calling Draw(CGRect rect)
just sounds wrong to me. Any help would be appreciated.
Currently I have the following code:
[Register("MenuHeaderView"), DesignTimeVisible(true)]
public class MenuHeaderView : UIView
{
private const int _margin = 5;
private UILabel _title;
private UILabel _subTitle;
public MenuHeaderView()
{
Initialize();
}
public MenuHeaderView(CGRect frame)
: base(frame)
{
Initialize();
}
public MenuHeaderView(IntPtr p)
: base(p)
{
Initialize();
}
[Export("Title"), Browsable(true)]
public string Title { get; set; }
[Export("SubTitle"), Browsable(true)]
public string SubTitle { get; set; }
private void Initialize()
{
AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;
// Create 'Title' label
_title = new UILabel()
{
BackgroundColor = UIColor.Clear,
Font = UIFont.BoldSystemFontOfSize(UIFont.SystemFontSize),
TextAlignment = UITextAlignment.Left,
TextColor = UIColor.White,
Text = "Verbeterapp",
TranslatesAutoresizingMaskIntoConstraints = false
};
// Create 'SubTitle' label
_subTitle = new UILabel()
{
BackgroundColor = UIColor.Clear,
Font = UIFont.SystemFontOfSize(UIFont.SystemFontSize),
TextAlignment = UITextAlignment.Left,
TextColor = UIColor.White,
Text = "JCI",
TranslatesAutoresizingMaskIntoConstraints = false
};
this.AddSubviews(new UIView[] { _title, _subTitle });
SetNeedsUpdateConstraints();
}
public override void UpdateConstraints()
{
if (NeedsUpdateConstraints())
SetupContraints();
base.UpdateConstraints();
}
private void SetupContraints()
{
var constraints = new List<NSLayoutConstraint>();
var viewMetrics = new Object[] {
"titleLabel", _title,
"subTitleLabel", _subTitle,
"margin", _margin
};
constraints.AddRange(
NSLayoutConstraint.FromVisualFormat(
"V:[titleLabel]-margin-[subTitleLabel]",
NSLayoutFormatOptions.AlignAllLeading,
viewMetrics
)
);
constraints.Add(
NSLayoutConstraint.Create (
_title,
NSLayoutAttribute.Left,
NSLayoutRelation.Equal,
this,
NSLayoutAttribute.Left,
1,
8
)
);
constraints.Add (
NSLayoutConstraint.Create(
_title,
NSLayoutAttribute.CenterY,
NSLayoutRelation.Equal,
this,
NSLayoutAttribute.CenterY,
1,
-_subTitle.Frame.Height
)
);
AddConstraints(constraints.ToArray());
}
}
Upvotes: 4
Views: 2471
Reputation: 14750
As allways: it depends on your requirements (small app/prototype for one platform or bigger app for multiple platforms). Therefore, your question is a bit opinion based.
Do you want to assign the Text just once? Then go for the Designer or set the Text property in your code. The remaining problem is, that you duplicate your text values with every supported platform. You have to set it in iOS, Android, UWP, Windows Phone, ... And if you want to change it, it is a pain.
I'd prefer databinding with MvvMCross. We use MvvMCross in nearly every of our Projects (since 3 years), because it provides a strict separation of view, data and services (with mondern approaches like IoC, MvvM, Databinding, Plugins, ViewModel to ViewModel navigation) and alot of abstractions of platfrom specific elements. The databinding mechanism allows you to change the viewed values without any pain. And if you want to change a static string, you have to do it only once. It adds of course a extra level that may be hard to understand, if you are new to Xamarin, Mobile and/or MvvM, but it's totally worth it.
Upvotes: 3