【发布时间】:2013-01-08 20:42:36
【问题描述】:
这是我在设置UIViews 和子视图时遇到的几个问题中的第一个。我有一个UIView,它在运行时动态定位在屏幕上。 UIView (master) 包含另一个 UIView (child),它包装了 UIImageView 和 UILabel。以下是我对这种安排的要求:
- 当设备旋转时,子
UIView必须保持在主UIView的中心。 -
UILabel中的文本可以很长也可以很短,带有图像和文本的子UIView必须保持居中。 - 我想避免子类化 UIView 来处理这种情况,我还想避免
willRotateToInterfaceOrientation.中的任何框架/定位代码我想通过 I.B. 中的一些autoresizingMask设置来处理所有这些。如果可能的话,可能还会强制调整代码大小。
这是 Interface Builder 中的控件排列(以红色突出显示):
使用 Interface Builder,autoresizingMask 属性已按如下方式设置,用于所述控件
-
UIView(master): 弹性上边距、弹性左边距、弹性右边距、弹性宽度 -
UIView(child): 弹性上边距、弹性下边距、弹性左边距、弹性右边距、弹性宽度、弹性高度。 (所有模式,无除外) -
UIImageView: 灵活的右边距 -
UILabel: 灵活的右边距
这是在纵向模式下在运行时以编程方式添加后的视图(带有图像和文本的红色条):
大师UIView的背景是浅红色的图像。孩子UIView的背景比这要暗一些,UILabel的背景更暗。我为它们着色,以便在应用响应旋转时看到它们的边界。
我很清楚:
- 它不是居中的,而是...
- 在将文本从 I.B 中的默认值更改为“此地图范围内没有数据”之后。到“TEST1, 123”。标签正确收缩。
这是在纵向添加然后旋转到横向模式后的视图:
从这里我可以看到:
- 它仍然没有居中,可能在旋转之前的原始帧原点
- UIView(子视图)已扩展以填充更多不应该的屏幕。
- UIView(主)已正确展开以填充屏幕宽度。
这就是让我走到现在的代码。我从 viewDidLoad 调用方法showNoDataStatusView:
// 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。 This question 和 this question 解释了这个问题。请参阅下面的类别代码。 - 我曾考虑过创建一个 UIView 子类来为我处理所有这些逻辑,但这似乎有点矫枉过正。在 I.B. 中安排这个应该很简单。对吗?
- 我已经尝试设置书中的每个调整大小蒙版设置,以及调整标签和视图大小调整发生的顺序以及主视图添加为子视图的点。似乎没有任何效果,因为我每次都得到奇怪的结果。
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(子)在它的父视图被添加到视图层次结构后没有正确居中。它看起来好像有合适的宽度,但不知何故保留了它在 I.B. 中的框架。当标签显示“此地图范围内没有数据”时。
我还想知道为什么它在设备旋转后没有居中,以及我在这里采用的方法是否明智。也许这导致了我遇到的其他问题。任何 UIView 布局帮助将不胜感激。
谢谢!
【问题讨论】:
标签: ios uiview subviews sizetofit