水平 UIStackView 居中
horizontal UIStackView centering
我正在尝试通过水平 UIStack 视图实现以下目标:
将显示未知数量的复选框(最多 5 个)。我希望它们像下面这样居中和等间距(2 个单独的图像):
如果我只需要一个复选框,它就会居中。
这是我目前得到的:
我现在很清楚,堆栈视图的左侧和右侧固定了 2 个复选框,其余复选框根据要求进行分布和间隔。
我希望一切都从堆栈视图的中心分布。
这是显示堆栈视图配置的代码:
UIStackView firstFiveCheckboxesStackView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Horizontal,
Distribution = UIStackViewDistribution.EqualSpacing,
Alignment = UIStackViewAlignment.Center,
Spacing = 10
};
尝试使用 UIStackViewAlignment.Fill
并将所有复选框包装在 UIView
中。
对于第二行,您需要添加三个空视图以使项目与顶行对齐。
要获得您描述的布局,您需要做的不仅仅是设置分布 属性。
- 假设您的 "checkbox" 视图具有固定宽度...
- 将 Stack View 的分布设置为
.Fill
- 添加一个 "spacer" 视图 in-between 每个 "checkbox" 视图
- 在开头和结尾添加一个"spacer"视图
- 将间隔视图的宽度设置为彼此相等
下面是 "spacer" 可见视图(青色背景)的外观:
背景清晰:
以及带有 5、4、3、2 和 1 个复选框的示例:
这是我用来获得这些结果的代码:
using Foundation;
using System;
using UIKit;
namespace MyTest
{
public class CheckBoxView : UIView
{
public CheckBoxView()
{
Initialize();
}
public CheckBoxView(IntPtr handle) : base(handle)
{
Initialize();
}
void Initialize()
{
this.Layer.BorderColor = UIColor.Black.CGColor;
this.Layer.BorderWidth = 1;
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
this.Layer.CornerRadius = Bounds.Width * (float)0.5;
}
}
public partial class ViewController : UIViewController
{
public ViewController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// change to .Cyan to see the spacers
UIColor spacerColor = UIColor.Clear;
UIStackView stacksView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Vertical,
Distribution = UIStackViewDistribution.Fill,
Alignment = UIStackViewAlignment.Fill,
Spacing = 20
};
for (int j = 5; j > 0; j -= 3)
{
UIStackView stackView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Horizontal,
Distribution = UIStackViewDistribution.Fill,
Alignment = UIStackViewAlignment.Fill,
Spacing = 0
};
UIView spacerView;
UIView prevSpacerView = null;
for (int i = 0; i < j; i++)
{
spacerView = new UIView();
spacerView.BackgroundColor = spacerColor;
var checkBox = new CheckBoxView();
stackView.AddArrangedSubview(spacerView);
stackView.AddArrangedSubview(checkBox);
checkBox.HeightAnchor.ConstraintEqualTo(40).Active = true;
checkBox.WidthAnchor.ConstraintEqualTo(checkBox.HeightAnchor).Active = true;
if (prevSpacerView != null)
{
spacerView.WidthAnchor.ConstraintEqualTo(prevSpacerView.WidthAnchor).Active = true;
}
prevSpacerView = spacerView;
}
spacerView = new UIView();
spacerView.BackgroundColor = spacerColor;
stackView.AddArrangedSubview(spacerView);
spacerView.WidthAnchor.ConstraintEqualTo(prevSpacerView.WidthAnchor).Active = true;
stacksView.AddArrangedSubview(stackView);
}
var sepView = new UIView();
sepView.HeightAnchor.ConstraintEqualTo(60).Active = true;
stacksView.AddArrangedSubview(sepView);
for (int j = 5; j > 0; j--)
{
UIStackView stackView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Horizontal,
Distribution = UIStackViewDistribution.Fill,
Alignment = UIStackViewAlignment.Fill,
Spacing = 0
};
UIView spacerView;
UIView prevSpacerView = null;
for (int i = 0; i < j; i++)
{
spacerView = new UIView();
spacerView.BackgroundColor = spacerColor;
var checkBox = new CheckBoxView();
stackView.AddArrangedSubview(spacerView);
stackView.AddArrangedSubview(checkBox);
checkBox.HeightAnchor.ConstraintEqualTo(40).Active = true;
checkBox.WidthAnchor.ConstraintEqualTo(checkBox.HeightAnchor).Active = true;
if (prevSpacerView != null)
{
spacerView.WidthAnchor.ConstraintEqualTo(prevSpacerView.WidthAnchor).Active = true;
}
prevSpacerView = spacerView;
}
spacerView = new UIView();
spacerView.BackgroundColor = spacerColor;
stackView.AddArrangedSubview(spacerView);
spacerView.WidthAnchor.ConstraintEqualTo(prevSpacerView.WidthAnchor).Active = true;
stacksView.AddArrangedSubview(stackView);
}
View.AddSubview(stacksView);
var stackConstraints = new[]
{
stacksView.TopAnchor.ConstraintEqualTo(View.TopAnchor, constant: 100),
stacksView.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor, constant: 40),
stacksView.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor, constant: -40),
};
NSLayoutConstraint.ActivateConstraints(stackConstraints);
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
}
}
}
我正在尝试通过水平 UIStack 视图实现以下目标:
将显示未知数量的复选框(最多 5 个)。我希望它们像下面这样居中和等间距(2 个单独的图像):
如果我只需要一个复选框,它就会居中。
这是我目前得到的:
我现在很清楚,堆栈视图的左侧和右侧固定了 2 个复选框,其余复选框根据要求进行分布和间隔。
我希望一切都从堆栈视图的中心分布。
这是显示堆栈视图配置的代码:
UIStackView firstFiveCheckboxesStackView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Horizontal,
Distribution = UIStackViewDistribution.EqualSpacing,
Alignment = UIStackViewAlignment.Center,
Spacing = 10
};
尝试使用 UIStackViewAlignment.Fill
并将所有复选框包装在 UIView
中。
对于第二行,您需要添加三个空视图以使项目与顶行对齐。
要获得您描述的布局,您需要做的不仅仅是设置分布 属性。
- 假设您的 "checkbox" 视图具有固定宽度...
- 将 Stack View 的分布设置为
.Fill
- 添加一个 "spacer" 视图 in-between 每个 "checkbox" 视图
- 在开头和结尾添加一个"spacer"视图
- 将间隔视图的宽度设置为彼此相等
下面是 "spacer" 可见视图(青色背景)的外观:
背景清晰:
以及带有 5、4、3、2 和 1 个复选框的示例:
这是我用来获得这些结果的代码:
using Foundation;
using System;
using UIKit;
namespace MyTest
{
public class CheckBoxView : UIView
{
public CheckBoxView()
{
Initialize();
}
public CheckBoxView(IntPtr handle) : base(handle)
{
Initialize();
}
void Initialize()
{
this.Layer.BorderColor = UIColor.Black.CGColor;
this.Layer.BorderWidth = 1;
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
this.Layer.CornerRadius = Bounds.Width * (float)0.5;
}
}
public partial class ViewController : UIViewController
{
public ViewController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// change to .Cyan to see the spacers
UIColor spacerColor = UIColor.Clear;
UIStackView stacksView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Vertical,
Distribution = UIStackViewDistribution.Fill,
Alignment = UIStackViewAlignment.Fill,
Spacing = 20
};
for (int j = 5; j > 0; j -= 3)
{
UIStackView stackView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Horizontal,
Distribution = UIStackViewDistribution.Fill,
Alignment = UIStackViewAlignment.Fill,
Spacing = 0
};
UIView spacerView;
UIView prevSpacerView = null;
for (int i = 0; i < j; i++)
{
spacerView = new UIView();
spacerView.BackgroundColor = spacerColor;
var checkBox = new CheckBoxView();
stackView.AddArrangedSubview(spacerView);
stackView.AddArrangedSubview(checkBox);
checkBox.HeightAnchor.ConstraintEqualTo(40).Active = true;
checkBox.WidthAnchor.ConstraintEqualTo(checkBox.HeightAnchor).Active = true;
if (prevSpacerView != null)
{
spacerView.WidthAnchor.ConstraintEqualTo(prevSpacerView.WidthAnchor).Active = true;
}
prevSpacerView = spacerView;
}
spacerView = new UIView();
spacerView.BackgroundColor = spacerColor;
stackView.AddArrangedSubview(spacerView);
spacerView.WidthAnchor.ConstraintEqualTo(prevSpacerView.WidthAnchor).Active = true;
stacksView.AddArrangedSubview(stackView);
}
var sepView = new UIView();
sepView.HeightAnchor.ConstraintEqualTo(60).Active = true;
stacksView.AddArrangedSubview(sepView);
for (int j = 5; j > 0; j--)
{
UIStackView stackView = new UIStackView
{
TranslatesAutoresizingMaskIntoConstraints = false,
Axis = UILayoutConstraintAxis.Horizontal,
Distribution = UIStackViewDistribution.Fill,
Alignment = UIStackViewAlignment.Fill,
Spacing = 0
};
UIView spacerView;
UIView prevSpacerView = null;
for (int i = 0; i < j; i++)
{
spacerView = new UIView();
spacerView.BackgroundColor = spacerColor;
var checkBox = new CheckBoxView();
stackView.AddArrangedSubview(spacerView);
stackView.AddArrangedSubview(checkBox);
checkBox.HeightAnchor.ConstraintEqualTo(40).Active = true;
checkBox.WidthAnchor.ConstraintEqualTo(checkBox.HeightAnchor).Active = true;
if (prevSpacerView != null)
{
spacerView.WidthAnchor.ConstraintEqualTo(prevSpacerView.WidthAnchor).Active = true;
}
prevSpacerView = spacerView;
}
spacerView = new UIView();
spacerView.BackgroundColor = spacerColor;
stackView.AddArrangedSubview(spacerView);
spacerView.WidthAnchor.ConstraintEqualTo(prevSpacerView.WidthAnchor).Active = true;
stacksView.AddArrangedSubview(stackView);
}
View.AddSubview(stacksView);
var stackConstraints = new[]
{
stacksView.TopAnchor.ConstraintEqualTo(View.TopAnchor, constant: 100),
stacksView.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor, constant: 40),
stacksView.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor, constant: -40),
};
NSLayoutConstraint.ActivateConstraints(stackConstraints);
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
}
}
}