调试有歧义的布局
1. 使用hasAmbiguousLayout来测试约束是否充分
如果约束充分,则返回NO,如果某个视图可能显示另一种不同的框架,则返回YES
2. 视图内容的大小通过每个视图的 intrinsicContentSize属性表达
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageWithName:@"icon.png"]];
NSLog(@"%@", NSStringFromCGSize(iv.intrinsicContentSize));
结果输出的大小与图片icon大小相同
无歧义的布局通常需要给每个坐标轴设置两个属性。当时图有一个内在内容大小时,则只需要设置两个属性中的一个。例如,可以把基于文本的控件或者图像视图放在其父视图的中心,它的布局将是无歧义的布局。内在内容大小和视图位置共同构成了充分制定的布局。
当改变了视图的内在内容时,需要调用==invalidateIntrinsicContentSize==方法,让AutoLayout知道在下次布局时重新计算。
3. 如果知道对齐矩形和整个图像的边界,可以自动计算需要传递给该方法的边缘inset
UIEdgeInsets BuildInsets(CGRect alignmentRect , CGRect imageBounds){
//Ensure alignment rect is fully within source,CGRectIntersection用来计算两个矩形的相交区域
CGRect targetRect = CGRectIntersection(alignmentRect,imageBounds);
//Calculate insets
UIEdgeInsets insets;
insets.left = CGRectGetMinX(targetRect) - CGRectGetMinX(imageBounds);
insets.right = CGRectGetMaxX(imageBounds) - CGRectGetMaxX(targetRect);
insets.top = CGRectGetMinY(targetRect) - CGRectGetMinY(imageBounds);
insets.bottom = CGRectGetMaxY(imageBounds) - CGRectGetMaxY(targetRect);
return insets;
}
4. translatesAutoresizingMaskIntoConstraints = NO;
当整个代码段将translatesAutoresizingMaskIntoConstraints设置为NO时,该默认的初始值实质上已被弃用(例如前面设置了初始的frame大小),可能导致宽度为0