我正在使用MonoTouch编写iOS应用程序,我想以编程方式定义我的所有UIViews以及定义其布局的AutoLayout约束。我目前正在尝试创建一个类似于Table的视图集合(行和列,而不是UITableView),并且我能够使用AutoLayout约束来调整列和行“边框”或标记。当我运行应用程序时它看起来很好,但我不断得到一个模糊的表格布局(使用HasAmbiguousLayout字段)。我把它简化为我的边框标记使用GreaterThanOrEqual(GTE)约束而不是Equal的事实,这是必需的,因为我想确保我的行和列适合任意数量的视图。
我的理解是,我可以使用GTE类型约束,而AutoLayout系统将尝试最小化该值,使其仍然是GTE(反之亦然,用于LTE约束)。例如,我希望我可以将视图的左侧egde GTE放置在另外两个视图的右边缘,这样布局求解器将确定左边缘的最小值,使得它仍然满足GTE的另一个右边缘视图。
我创建了一个简单的示例,但我不确定为什么会出现模糊的布局。我在MonoTouch中创建了一个单视图项目,并以编程方式添加了一个UIView框作为我的容器(在更复杂的示例中包含多行和多列视图)。然后我只在框视图中添加一个子视图,一个名为myLabel的UILabel。我添加约束以将标签放在框中,将框放在父视图中,并设置框的右边和底边(这是关键部分):
public partial class AutoLayoutTestViewController : UIViewController
{
public AutoLayoutTestViewController () : base ("AutoLayoutTestViewController", null)
{
UIView box = new UIView ();
box.BackgroundColor = UIColor.Green;
box.TranslatesAutoresizingMaskIntoConstraints = false;
View.AddSubview (box);
View.AddConstraint (NSLayoutConstraint.Create (box, NSLayoutAttribute.Top, NSLayoutRelation.Equal, View, NSLayoutAttribute.Top, 1.0f, 50f));
View.AddConstraint (NSLayoutConstraint.Create (box, NSLayoutAttribute.Left, NSLayoutRelation.Equal, View, NSLayoutAttribute.Left, 1.0f, 0f));
UILabel myLabel = new UILabel ();
myLabel.Text = "My Label";
myLabel.BackgroundColor = UIColor.Red;
myLabel.TranslatesAutoresizingMaskIntoConstraints = false;
box.AddSubview (myLabel);
box.AddConstraint (NSLayoutConstraint.Create (myLabel, NSLayoutAttribute.Top, NSLayoutRelation.Equal, box, NSLayoutAttribute.Top, 1.0f, 10f));
box.AddConstraint (NSLayoutConstraint.Create (myLabel, NSLayoutAttribute.Left, NSLayoutRelation.Equal, box, NSLayoutAttribute.Left, 1.0f, 10f));
// IMPORTANT CONSTRAINTS
box.AddConstraint (NSLayoutConstraint.Create (box, NSLayoutAttribute.Bottom, NSLayoutRelation.GreaterThanOrEqual, myLabel, NSLayoutAttribute.Bottom, 1.0f, 10f));
box.AddConstraint (NSLayoutConstraint.Create (box, NSLayoutAttribute.Right, NSLayoutRelation.GreaterThanOrEqual, myLabel, NSLayoutAttribute.Right, 1.0f, 10f));
}
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLayoutSubviews ()
{
base.ViewDidLayoutSubviews ();
foreach (UIView v in View.Subviews) {
if (v.HasAmbiguousLayout) {
Console.WriteLine ("WARNING: View {0} has ambiguous layout!", v);
}
}
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
}
}
以下屏幕截图显示框和标签显示为我想要的,但是当视图控制器完成布局子视图时,我收到的信息是我的框具有不明确的布局。如果我将框的右边和底边的“重要约束”更改为等于而不是GreaterThanOrEqual,则布局不再模糊。同样,重要的是我能够将我的约束指定为GTE,因为我在行和列中设置了任意数量的视图的边框,因此当我向表中添加新视图时,我确保我的权利边缘被约束为GTE的所有视图,并且类似地用于底边。我不能在我的应用程序中使用严格等于,因为我不知道表中的哪个子视图将是最右边或最底部的视图;这就是GTE限制的原因。
我的问题是:为什么我不能在这里使用GTE约束来获取我的盒子视图而不会出现模糊的布局?如果这个简单的例子不起作用,你怎么会使用GTE约束(它们都是模棱两可的,否则你会首先将它们指定为Equal)?
感谢您的帮助,
凸轮
答案 0 :(得分:1)
通常我会做同样的事情,使用GTE来确保某个方面的某些内容有限,但是然后添加另一个具有较低优先级的约束来尝试执行其他操作,例如将视图置于另一个视图中。你必须要有创意。我发现的最好的方法是使用铅笔和纸,画出一个例子,并尝试构建我需要什么约束的地方。
我不相信系统可以平等地分配不等式 - 如果左边有一个,右边有一个,它该怎么办?我使用不等式来确保永远不会超过某个最大值,然后使用不等式来尝试实现某个目标(即居中)。