这是我在设置一些UIView
s 和子视图时遇到的几个问题中的第一个。我有一个UIView
在运行时动态定位在屏幕上的。那UIView
(master) 包含另一个UIView
(child) 包装 aUIImageView
和 a UILabel
。以下是我对这种安排的要求:
- 设备旋转时,子设备
UIView
必须保持在主设备的中心。UIView
- 中的文字
UILabel
可以很长也可以很短,UIView
带有图像和文字的孩子仍然必须保持居中。 - 我想避免子类化 UIView 来处理这种情况,我还想避免任何框架/定位代码,
willRotateToInterfaceOrientation.
我想用autoresizingMask
IB 中的一些设置来处理所有这些,如果可能的话,可能还有一些强制调整大小的代码。
这是 Interface Builder 中的控件排列(以红色突出显示):
使用 Interface Builder,autoresizingMask
属性已像这样设置,用于描述的控件
UIView
(master): 弹性上边距、弹性左边距、弹性右边距、弹性宽度UIView
(子):灵活的上边距,灵活的下边距,灵活的左边距,灵活的右边距,灵活的宽度,灵活的高度。(所有模式,无除外)UIImageView
: 灵活的右边距UILabel
: 灵活的右边距
这是在纵向模式下在运行时以编程方式添加后的视图(带有图像和文本的红色条):
主人UIView
的背景是浅红色的图像。childUIView
的背景比这稍微暗一些,而UILabel
's 的背景更暗。我为它们着色,以便在应用程序响应旋转时可以看到它们的边界。
我很清楚:
- 它不是居中的,但...
- 在将文本从“此地图范围内没有数据”更改为 IB 中的默认值后。到“TEST1, 123”。标签正确收缩。
这是在纵向添加然后旋转到横向模式后的视图:
从这里我可以看到:
- 它仍然没有居中,并且可能在旋转之前位于其原始框架原点
- UIView(子)已扩展以填充更多不应该的屏幕。
- UIView(主)已正确扩展以填充屏幕宽度。
这就是让我走到现在的代码。showNoDataStatusView
我从 viewDidLoad调用该方法:
// Assuming
#define kStatusViewHeight 20
- (void)showNoDataStatusView {
if (!self.noDataStatusView.superview) {
self.noDataStatusView.frame = CGRectMake(self.mapView.frame.origin.x,
self.mapView.frame.origin.y,
self.mapView.frame.size.width,
kStatusViewHeight);
self.noDataStatusView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bgRedStatus.png"]];
// Position the label view in the center
self.noDataStatusLabelView.center = CGPointMake(self.noDataStatusView.frame.size.width/2,
self.noDataStatusView.frame.size.height/2);
// Test different text
self.noDataStatusLabel.text = @"Testing, 123.";
// Size to fit label
[self.noDataStatusLabel sizeToFit];
// Test the status label view resizing
[self.noDataStatusLabelView resizeToFitSubviews];
// Add view as subview
[self.view addSubview:self.noDataStatusView];
}
}
请注意以下事项:
resizeToFitSubviews
是我放置在 UIView 上的一个类别,一旦我发现 UIView 不会自动调整大小以适应它们的子视图,即使你调用sizeToFit
. 这个问题,这个问题解释了这个问题。请参阅下面的类别代码。- 我曾考虑过创建一个 UIView 子类来为我处理所有这些逻辑,但这似乎有点矫枉过正。在IB中安排这个应该很简单吧?
- 我已经尝试设置书中的每个调整大小掩码设置,以及调整标签和视图大小调整发生的顺序以及将主视图添加为子视图的点。似乎没有任何效果,因为我每次都会得到奇怪的结果。
UIView resizeToFitSubviews 类实现方法:
-(void)resizeToFitSubviews
{
float width = 0;
float height = 0;
// Loop through subviews to determine max height/width
for (UIView *v in [self subviews]) {
float fw = v.frame.origin.x + v.frame.size.width;
float fh = v.frame.origin.y + v.frame.size.height;
width = MAX(fw, width);
height = MAX(fh, height);
}
[self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y, width, height)];
}
我想知道的是为什么UIView
(子)在将其超级视图添加到视图层次结构后没有正确居中。它看起来好像得到了正确的宽度,但是当标签显示“此地图范围内没有数据”时,它以某种方式保留了它在 IB 中的帧。
我还想知道为什么它在设备旋转后没有居中,以及我在这里采用的方法是否明智。也许这导致了我遇到的其他问题。任何 UIView 布局帮助将不胜感激。
谢谢!