Xamarin iOS 自定义视图

Posted

技术标签:

【中文标题】Xamarin iOS 自定义视图【英文标题】:Xamarin iOS custom view 【发布时间】:2016-02-23 10:37:14 【问题描述】:

我创建了一个自定义视图(从 UIView 派生的新类)。此视图旨在用作我的 ios 应用程序中的标题,并且基本上包含两个标签,称为“标题”和“子标题”。我创建了两个匹配的字符串属性,可用于设置“标题”和“子标题”标签的文本。

我的问题是,将提供给属性的字符串值分配给标签的 .text 属性的最佳位置是什么?

我知道当我覆盖Draw(CGRect rect) 方法并在此处分配值时它会起作用(并在属性值更改时调用SetNeedsDisplay() 方法)。然而,打电话给Draw(CGRect rect) 对我来说是错误的。任何帮助将不胜感激。

目前我有以下代码:

[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());
    

【问题讨论】:

【参考方案1】:

一如既往:这取决于您的要求(一个平台的小型应用程序/原型或多个平台的大型应用程序)。因此,您的问题有点基于意见。

您想只分配文本一次吗?然后选择 Designer 或在代码中设置 Text 属性。剩下的问题是,您在每个受支持的平台上都复制了文本值。你必须在 iOS、android、UWP、Windows Phone 中设置它......而且如果你想改变它,那就很痛苦了。

我更喜欢使用 MvvMCross 进行数据绑定。我们几乎在每个项目中都使用 MvvMCross(从 3 年开始),因为它提供了视图、数据和服务的严格分离(使用 IoC、MvvM、数据绑定、插件、ViewModel 到 ViewModel 导航等现代方法)以及许多抽象平台特定元素。数据绑定机制允许您轻松更改查看的值。如果你想改变一个静态字符串,你只需要做一次。如果您是 Xamarin、Mobile 和/或 MvvM 的新手,它当然会增加一个可能难以理解的额外级别,但这是完全值得的。

【讨论】:

抱歉反应迟了,感谢您的回复。但是我的问题更多的是关于自定义视图的内部(因为这应该是一个可重用的控件/视图)。主要是如果自定义视图本身的“绘制”方法是设置文本属性的正确位置。从外部我肯定会使用 MvvmCross 绑定到控件。我问的原因是,不知何故我觉得'Draw'方法更适合真正做图形(但这只是一种感觉)。 好的,而不是像这样简单地实现属性:public string SubTitle get return _subTitle.Text; set _subTitle.Text = value; 当值改变时这是否也会自动更新视图? 是的,如果您使用数据绑定并且不通过一次性绑定进行绑定。在带有 Fluent 绑定 github.com/MvvmCross/MvvmCross/wiki/Databinding#fluent 的 MvvMCross 中,它看起来类似于:bindig.Bind(myHeader).For(v =&gt; v.SubTitle).To(vm =&gt; vm.SubTitle) 非常感谢您的帮助!【参考方案2】:

对于 Xamarin.iOS,您可以尝试类似 this.

【讨论】:

以上是关于Xamarin iOS 自定义视图的主要内容,如果未能解决你的问题,请参考以下文章

从自定义列表 Xamarin 中设置所选列表视图项的背景颜色

是否可以在 xamarin 的自定义对话框中添加列表视图

Xamarin XAML语言教程ContentView视图作为自定义视图的父类

csharp C# - Xamarin.Forms自定义简单徽章视图+通过自定义渲染器的圆角框视图

Xamarin 自定义视图 ClassNotFoundException

使用 Xamarin 在键盘上方添加自定义视图