C# 如何在UILabel和两个UIImageView之间设置约束?

C# 如何在UILabel和两个UIImageView之间设置约束?,c#,ios,swift,xamarin.ios,C#,Ios,Swift,Xamarin.ios,我正在尝试制作一个包含两个图像和一个标签的水平视图: 第一幅图像应定位在视图的左侧 第二幅图像应定位在视图的右侧 标签应固定在两个图像之间 视图的大小应与相同图像的高度一致。它应该覆盖整个屏幕宽度 我想要达到的是这样的效果(蓝色的选定元素): 这是我的密码: public partial class ViewController : UIViewController { public ViewController(IntPtr handle) : base(han

我正在尝试制作一个包含两个图像和一个标签的水平视图:

  • 第一幅图像应定位在视图的左侧
  • 第二幅图像应定位在视图的右侧
  • 标签应固定在两个图像之间
  • 视图的大小应与相同图像的高度一致。它应该覆盖整个屏幕宽度
  • 我想要达到的是这样的效果(蓝色的选定元素):

    这是我的密码:

       public partial class ViewController : UIViewController
        {
            public ViewController(IntPtr handle) : base(handle)
            {
            }
    
            public override void ViewDidLoad()
            {
                base.ViewDidLoad();
    
                UIStackView header = new UIStackView();
                header.Axis = UILayoutConstraintAxis.Horizontal;
                View.AddSubview(header);
    
                //< color name = "healthy_green" >#409900</color>
                var healthy_green = new UIColor(red: 0.25f, green: 0.60f, blue: 0.00f, alpha: 1.00f);
                //< color name = "optimistic_orange" >#FF5F00</color>
                var optimistic_orange = new UIColor(red: 1.00f, green: 0.37f, blue: 0.00f, alpha: 1.00f);
    
                // Enable Auto Layout
                header.TranslatesAutoresizingMaskIntoConstraints = false;
                var ic_qol_image = UIImage.FromBundle("ic_qol");
                ic_qol_image.ApplyTintColor(healthy_green);
                var ic_qol = new UIImageView(ic_qol_image);
                ic_qol.SizeToImage();
    
                var qol_title = new UILabel { TranslatesAutoresizingMaskIntoConstraints = false, Text = @"Quality of Life" };
    
                var ic_edit_image = UIImage.FromBundle("ic_edit");
                ic_edit_image.ApplyTintColor(optimistic_orange);
                var ic_edit = new UIImageView(ic_edit_image);
                ic_edit.SizeToImage();
    
                var qolHeaderViews = new UIView[] { ic_qol, qol_title, ic_edit };
                header.AddSubviews(qolHeaderViews);
    
                header.Anchor(top: View.SafeAreaLayoutGuide.TopAnchor, leading: View.LeadingAnchor, trailing: View.TrailingAnchor);
                ic_qol.Anchor(top: header.TopAnchor, leading: header.LeadingAnchor);
                ic_edit.Anchor(top: header.TopAnchor, trailing: header.TrailingAnchor);
                qol_title.Anchor(top: View.SafeAreaLayoutGuide.TopAnchor, leading: ic_qol.RightAnchor, trailing: ic_edit.RightAnchor, padding: new UIEdgeInsets(0, 10, 0, 0));   <=== fails here.
            }
           public override void DidReceiveMemoryWarning()
            {
                base.DidReceiveMemoryWarning();
                // Release any cached data, images, etc that aren't in use.
            }
        }
    
        internal static class extensions
        {
            // https://stackoverflow.com/a/48601685/15186
            internal static void SizeToImage(this UIImageView uIImageView)
            {
                //Grab loc
                var xC = uIImageView.Center.X;
                var yC = uIImageView.Center.Y;
    
                //Size to fit
                uIImageView.Frame = new CGRect(x: 0, y: 0, width: uIImageView.Image.Size.Width / 2, height: uIImageView.Image.Size.Height / 2);
    
                //Move to loc
                uIImageView.Center = new CGPoint(x: xC, y: yC);
            }
    
            internal static void FillParentView(this UIView uIView)
            {
                uIView.Anchor(top: uIView.Superview?.TopAnchor, leading: uIView.Superview?.LeadingAnchor, bottom: uIView.Superview?.BottomAnchor, trailing: uIView.Superview.TrailingAnchor);
            }
    
            internal static void AnchorSize(this UIView uIView, UIView to)
            {
                uIView.WidthAnchor.ConstraintEqualTo(to.WidthAnchor).Active = true;
                uIView.HeightAnchor.ConstraintEqualTo(to.HeightAnchor).Active = true;
            }
    
            internal static void Anchor(this UIView uIView, NSLayoutYAxisAnchor top = null, NSLayoutXAxisAnchor leading = null, NSLayoutYAxisAnchor bottom = null, NSLayoutXAxisAnchor trailing = null, UIEdgeInsets padding = default, CGSize size= default)
            {
                uIView.TranslatesAutoresizingMaskIntoConstraints = false;
                if (top != null)
                {
                    uIView.TopAnchor.ConstraintEqualTo(top, padding.Top).Active = true;
                }
    
                if (leading != null)
                {
                    uIView.LeadingAnchor.ConstraintEqualTo(leading, padding.Left).Active = true; <=== fails here.
                }
    
                if (bottom != null)
                {
                    uIView.BottomAnchor.ConstraintEqualTo(bottom, -padding.Bottom).Active = true;
                }
    
                if (trailing != null)
                {
                    uIView.TrailingAnchor.ConstraintEqualTo(trailing, -padding.Right).Active = true;
                }
    
                if ( size.Width != 0)
                {
                    uIView.WidthAnchor.ConstraintEqualTo(size.Width).Active = true;
                }
    
                if ( size.Height != 0)
                {
                    uIView.HeightAnchor.ConstraintEqualTo(size.Height).Active = true;
                }
            }
        }
    
    public部分类ViewController:UIViewController
    {
    公共视图控制器(IntPtr句柄):基本(句柄)
    {
    }
    公共覆盖无效ViewDidLoad()
    {
    base.ViewDidLoad();
    UIStackView标头=新的UIStackView();
    header.Axis=UILayoutConstraints.Horizontal;
    视图.添加子视图(标题);
    //#409900
    var Health_green=新UIColor(红色:0.25f,绿色:0.60f,蓝色:0.00f,阿尔法:1.00f);
    //#FF5F00
    var Optimization_orange=新UIColor(红色:1.00f,绿色:0.37f,蓝色:0.00f,阿尔法:1.00f);
    //启用自动布局
    header.TranslatesAutoresizingMaskIntoConstraints=false;
    var ic_qol_image=UIImage.FromBundle(“ic_qol”);
    ic_qol_图像。ApplyIntColor(健康_绿色);
    var ic_qol=新的UIImageView(ic_qol_图像);
    ic_qol.SizeToImage();
    var qol_title=new UILabel{translatesAutoresizengmaskintoConstraints=false,Text=@“生活质量”};
    var ic_edit_image=UIImage.FromBundle(“ic_edit”);
    ic_编辑_图像。ApplyIntColor(橙色);
    var ic_edit=新的UIImageView(ic_edit_图像);
    ic_edit.SizeToImage();
    var qolHeaderViews=新UIView[]{ic_-qol,qol_-title,ic_-edit};
    header.addSubview(qolHeaderViews);
    header.Anchor(顶部:View.SafeAreaLayoutGuide.TopAnchor,前导:View.LeadingAnchor,尾随:View.TrailingAnchor);
    ic_质量锚(顶部:header.TopAnchor,前导:header.LeadingAnchor);
    ic_编辑锚定(顶部:header.TopAnchor,尾部:header.TrailingAnchor);
    
    qol_title.Anchor(顶部:View.saferealayoutguide.TopAnchor,前导:ic_qol.rightachor,尾随:ic_edit.rightachor,padding:new-uiedgeinset(0,10,0,0));您可以通过“水平”堆栈视图轻松实现此布局

    注意:我不使用xamarin/c#,所以我只描述一下您想要做什么

    • 创建堆栈视图
    • 将其属性设置为
      • 轴:水平
      • 分配:填充
      • 对齐:居中(这是子视图的垂直对齐)
      • 间距:8(子视图之间可能需要一点间距)
    • 创建2个图像视图
      • 将图像加载到每个图像视图中
      • 根据需要设置图像视图的宽度和高度约束(看起来您使用的是图像高度和宽度的1/2?)
    • 创建一个标签
    • 将图像视图和标签作为排列的子视图添加到堆栈视图中
      • header.AddArrangedSubview(ic_qol);
      • header.AddArrangedSubview(qol_title);
      • header.AddArrangedSubview(ic_编辑);
    • 将堆栈视图添加到视图中
      • View.AddSubview(标题);
    最后一步是添加约束,将堆栈视图置于顶部,跨越视图的宽度:

    // Get the parent view's layout
    var margins = View.LayoutMarginsGuide;
    
    // Pin the top edge of the stackView to the margin
    header.TopAnchor.ConstraintEqualTo (margins.TopAnchor).Active = true;
    
    // Pin the leading edge of the stackView to the margin
    header.LeadingAnchor.ConstraintEqualTo (margins.LeadingAnchor).Active = true;
    
    // Pin the trailing edge of the stackView to the margin
    header.TrailingAnchor.ConstraintEqualTo (margins.TrailingAnchor).Active = true;
    
    结果应该如下所示:

    每个imageView的宽度限制为40磅,高度与宽度相等。标签有一个青色背景,便于查看布局,文本对齐位于中间。轮廓正好在那里,因此我们可以看到stackView的框架

    在运行时,如果没有框架轮廓:


    您可以通过“水平”堆栈视图轻松实现此布局

    注意:我不使用xamarin/c#,所以我只描述一下您想要做什么

    • 创建堆栈视图
    • 将其属性设置为
      • 轴:水平
      • 分配:填充
      • 对齐:居中(这是子视图的垂直对齐)
      • 间距:8(子视图之间可能需要一点间距)
    • 创建2个图像视图
      • 将图像加载到每个图像视图中
      • 根据需要设置图像视图的宽度和高度约束(看起来您使用的是图像高度和宽度的1/2?)
    • 创建一个标签
    • 将图像视图和标签作为排列的子视图添加到堆栈视图中
      • header.AddArrangedSubview(ic_qol);
      • header.AddArrangedSubview(qol_title);
      • header.AddArrangedSubview(ic_编辑);
    • 将堆栈视图添加到视图中
      • View.AddSubview(标题);
    最后一步是添加约束,将堆栈视图置于顶部,跨越视图的宽度:

    // Get the parent view's layout
    var margins = View.LayoutMarginsGuide;
    
    // Pin the top edge of the stackView to the margin
    header.TopAnchor.ConstraintEqualTo (margins.TopAnchor).Active = true;
    
    // Pin the leading edge of the stackView to the margin
    header.LeadingAnchor.ConstraintEqualTo (margins.LeadingAnchor).Active = true;
    
    // Pin the trailing edge of the stackView to the margin
    header.TrailingAnchor.ConstraintEqualTo (margins.TrailingAnchor).Active = true;
    
    结果应该如下所示:

    每个imageView的宽度限制为40磅,高度与宽度相等。标签有一个青色背景,便于查看布局,文本对齐位于中间。轮廓正好在那里,因此我们可以看到stackView的框架

    在运行时,如果没有框架轮廓:


    UIStackView的目的是排列其子视图。
    UILabel
    UIImag之间的约束。
    UILabel
    UIImag之间的约束