使用 Xamarin 在 iOS 中使用自动布局绘制元素的相对定位
Relative positioning of drawn elements with autolayout in iOS using Xamarin
我目前正在开发一个 Xamarin iOS 应用程序,它使用自动布局将元素放置在我的视图中。
我想根据通过自动布局定位的其他子视图绘制元素并定位它们。
我的问题是,draw
方法在创建子视图布局之前以及它们在我的视图中定位之前被调用,所以我无法将相对位置作为起点传递给要绘制的视图。
我只能通过在 ViewDidLayoutSubviews
而不是 ViewDidLoad
方法中添加绘制的子视图来做到这一点。我认为这不是一个非常优雅的解决方案,我想知道是否有任何其他方法可以定位必须通过相对起点绘制的元素?
这是一些示例代码:
A ViewController 显示元素:
public class QuestionViewController : BaseController {
private UILabel _infoLabel;
private UIButton _button1;
public override void ViewDidLoad() {
UIView containerView = View;
containerView.BackgroundColor = UIColor.White;
var constraints = new List<NSLayoutConstraint>();
_infoLabel = new UILabel()
{
IsAccessibilityElement = true,
TranslatesAutoresizingMaskIntoConstraints = false,
Text = "My Info Label",
LineBreakMode = UILineBreakMode.WordWrap,
Lines = 2,
Font = UICore.TextFont,
TextColor = UICore.TextColor
};
containerView.AddSubview(_infoLabel);
constraints.Add(NSLayoutConstraint.Create(_infoLabel, NSLayoutAttribute.Top, NSLayoutRelation.Equal, containerView, NSLayoutAttribute.Bottom, 1f, 10f));
constraints.Add(NSLayoutConstraint.Create(_infoLabel, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, containerView, NSLayoutAttribute.Leading, 1f, 10f));
constraints.Add(NSLayoutConstraint.Create(_infoLabel, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, containerView, NSLayoutAttribute.Trailing, 1f, -10f));
containerView.AddConstraints(constraints.ToArray());
base.ViewDidLoad();
}
public override void ViewDidLayoutSubviews() {
var containerView = View;
var myCircle = new CircleView(new RectangleF((float)_infoLabel.Frame.X, (float)_infoLabel.Frame.Bottom, 60, 60), UIColor.Red, "TEST");
containerView.AddSubview(myCircle);
base.ViewDidLayoutSubviews();
}
}
画圆的CircleView:
public class CircleView : UIView {
private UIColor _color;
private string _label;
public CircleView()
{
Initialize();
}
public CircleView(RectangleF bounds, UIColor color, string label) : base(bounds) {
_label = label;
_color = color;
Initialize();
}
void Initialize()
{
BackgroundColor = UIColor.White;
}
public override void Draw(CGRect rect) {
var context = UIGraphics.GetCurrentContext();
context.SetFillColor(_color.CGColor);
context.FillEllipseInRect(rect);
}
}
我终于找到了适合我的答案。
在 ViewDidLoad
方法中我创建了另一个子视图,将 circleView 添加到该子视图并将子视图添加到我的 containerView。 circleView 获取起点 0,0 并且我为子视图添加约束以将其定位在 containerView 中:
var dummyView = new UIView();
dummyView.AddSubview(new CircleView(new RectangleF(0f, 0f, 60, 60), UIColor.Red, "TEST");)
containerView.AddSubview(dummyView);
constraints.Add(NSLayoutConstraint.Create(dummyView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, _infoLabel, NSLayoutAttribute.Bottom, 1f, 10f));
constraints.Add(NSLayoutConstraint.Create(dummyView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, containerView, NSLayoutAttribute.Leading, 1f, 10f));
我目前正在开发一个 Xamarin iOS 应用程序,它使用自动布局将元素放置在我的视图中。 我想根据通过自动布局定位的其他子视图绘制元素并定位它们。
我的问题是,draw
方法在创建子视图布局之前以及它们在我的视图中定位之前被调用,所以我无法将相对位置作为起点传递给要绘制的视图。
我只能通过在 ViewDidLayoutSubviews
而不是 ViewDidLoad
方法中添加绘制的子视图来做到这一点。我认为这不是一个非常优雅的解决方案,我想知道是否有任何其他方法可以定位必须通过相对起点绘制的元素?
这是一些示例代码:
A ViewController 显示元素:
public class QuestionViewController : BaseController {
private UILabel _infoLabel;
private UIButton _button1;
public override void ViewDidLoad() {
UIView containerView = View;
containerView.BackgroundColor = UIColor.White;
var constraints = new List<NSLayoutConstraint>();
_infoLabel = new UILabel()
{
IsAccessibilityElement = true,
TranslatesAutoresizingMaskIntoConstraints = false,
Text = "My Info Label",
LineBreakMode = UILineBreakMode.WordWrap,
Lines = 2,
Font = UICore.TextFont,
TextColor = UICore.TextColor
};
containerView.AddSubview(_infoLabel);
constraints.Add(NSLayoutConstraint.Create(_infoLabel, NSLayoutAttribute.Top, NSLayoutRelation.Equal, containerView, NSLayoutAttribute.Bottom, 1f, 10f));
constraints.Add(NSLayoutConstraint.Create(_infoLabel, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, containerView, NSLayoutAttribute.Leading, 1f, 10f));
constraints.Add(NSLayoutConstraint.Create(_infoLabel, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, containerView, NSLayoutAttribute.Trailing, 1f, -10f));
containerView.AddConstraints(constraints.ToArray());
base.ViewDidLoad();
}
public override void ViewDidLayoutSubviews() {
var containerView = View;
var myCircle = new CircleView(new RectangleF((float)_infoLabel.Frame.X, (float)_infoLabel.Frame.Bottom, 60, 60), UIColor.Red, "TEST");
containerView.AddSubview(myCircle);
base.ViewDidLayoutSubviews();
}
}
画圆的CircleView:
public class CircleView : UIView {
private UIColor _color;
private string _label;
public CircleView()
{
Initialize();
}
public CircleView(RectangleF bounds, UIColor color, string label) : base(bounds) {
_label = label;
_color = color;
Initialize();
}
void Initialize()
{
BackgroundColor = UIColor.White;
}
public override void Draw(CGRect rect) {
var context = UIGraphics.GetCurrentContext();
context.SetFillColor(_color.CGColor);
context.FillEllipseInRect(rect);
}
}
我终于找到了适合我的答案。
在 ViewDidLoad
方法中我创建了另一个子视图,将 circleView 添加到该子视图并将子视图添加到我的 containerView。 circleView 获取起点 0,0 并且我为子视图添加约束以将其定位在 containerView 中:
var dummyView = new UIView();
dummyView.AddSubview(new CircleView(new RectangleF(0f, 0f, 60, 60), UIColor.Red, "TEST");)
containerView.AddSubview(dummyView);
constraints.Add(NSLayoutConstraint.Create(dummyView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, _infoLabel, NSLayoutAttribute.Bottom, 1f, 10f));
constraints.Add(NSLayoutConstraint.Create(dummyView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, containerView, NSLayoutAttribute.Leading, 1f, 10f));