以编程方式创建具有多个标签的 UIView
-
20-12-2019 - |
题
Xcode Interface Builder 问题
就我个人而言,我不喜欢 Xcode 中界面生成器的工作方式。在这个例子中,我试图创建一个相当复杂的视图控制器。上 viewDidLoad
视图控制器的我显示了一个自定义警报视图(本身)。它实际上不是一个警报视图,而是一个向用户显示一些信息的视图。我有一个暗淡的背景视图和在此之上的视图。如果我尝试在界面生成器中创建它,它会变得过于复杂,因为您无法在后台选择视图并移动它们等,而不会将子视图放入错误的视图等等......
设想
我想做的是创建一个包含一些标签和按钮的视图。视图控制器具有基于此的难度属性,它将在标签/标签数量中具有不同的文本。
IE。简单 -- 3 个标签
硬 -- 4 个标签
我创建了 dimmedView 和alert(styled)View,如下所示:
// Setup the dimmedView
UIView *dimmedView = [[UIView alloc] initWithFrame:self.view.frame];
dimmedView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.6];
// Setup the startingAlertView
UIView *startingAlertView = [[UIView alloc] init];
startingAlertView.backgroundColor = [UIColor whiteColor];
然后,我根据某种逻辑创建三/四个标签,并将必要的标签添加到 startingAlertView
也基于逻辑。
显而易见的问题是,在任何时候都没有设置视图框架。这意味着它返回 0,0,0,0。我希望发生的是根据添加的标签获取所需高度的视图。
我正在为 IOS7 构建并使用自动布局。我是否应该设置约束来调整视图中的相关高度和位置?
解决方案
我正在为 IOS7 构建并使用自动布局。我是否应该设置约束来调整视图中的相关高度和位置?
是的。你不使用 initWithFrame:
在自动布局下,或者更确切地说,您可以,但框架会被忽略。使用框架创建您的调光视图 CGRectZero
, , 环境 translatesAutoresizingMasksToConstraints
为“否”,将其添加到主视图并创建约束,将其固定到超级视图的所有边缘。
然后,添加您的警报视图,再次使用零帧和 translates...
属性设置为 NO。创建约束以使该视图在调光视图中居中。该视图将从其子视图获取其大小,因为标签具有固有大小。
将标签添加为该视图的子视图,框架为零且 translates...
设置为否。根据它们的内容,您可能希望设置首选最大布局宽度或宽度约束。
创建约束,将标签固定到超级视图的左边缘和右边缘,并将标签排列在垂直“堆栈”中。在每种情况下,您都可以添加填充,为警报添加一点边框。
这看起来像是大量代码,因此您可能需要阅读我写的文章 自动布局的视觉格式 和 在代码中创建约束, ,与相关联的 自动布局便利类别 让您的生活更轻松。
其他提示
如果您将进入自动布局路由,则可以添加将在每个标签之间保留适当的空间的约束以及与第一个和最后一个标签的视图顶部和底部之间的适当空间。但是,如果您未在界面构建器中执行此操作,您也可以使用自动布局跳过,因为只需在添加标签时调整视图的高度就很简单。
您将首先将视图的高度设置为您想要在标签周围的顶部和底部空间的大小。然后,每次添加标签时,都会添加标签的高度加上您在标签之间放置的空间的高度。
您也可以等到您添加所需的所有标签,然后将高度设置为底部标签的y位置加上它的高度加上您想要在标签周围拥有的底部空间。
是,使用autolayout您可以从父视图获取界限。
这里是一个快速的例子,请注意,我们不使用帧,并使用cgrectzero for我们的Uilabels,定位来自updateConstraints
。我正在使用视觉格式语言如果您以编程方式进行,我推荐的标签。
在这里,我们正在制作标签父视图的宽度,然后刚刚堆叠在一起。
#import "View.h"
@implementation View{
UILabel *_label1;
UILabel *_label2;
UILabel *_label3;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_label1 = [[UILabel alloc] initWithFrame:CGRectZero];
_label1.translatesAutoresizingMaskIntoConstraints = NO;
_label1.text = @"LABEL 1";
_label2 = [[UILabel alloc] initWithFrame:CGRectZero];
_label2.translatesAutoresizingMaskIntoConstraints = NO;
_label2.text = @"LABEL 2";
_label3 = [[UILabel alloc] initWithFrame:CGRectZero];
_label3.translatesAutoresizingMaskIntoConstraints = NO;
_label3.text = @"LABEL 3";
[self addSubview:_label1];
[self addSubview:_label2];
[self addSubview:_label3];
}
[self updateConstraintsIfNeeded];
return self;
}
-(void)updateConstraints
{
[super updateConstraints];
NSDictionary *_viewsDictionary = NSDictionaryOfVariableBindings(_label1,_label2,_label3);
// Set the contraintsto span the entire width of the super view
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_label1]-|"
options:0
metrics:nil
views:_viewsDictionary];
[self addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_label2]-|"
options:0
metrics:nil
views:_viewsDictionary];
[self addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_label3]-|"
options:0
metrics:nil
views:_viewsDictionary];
[self addConstraints:constraints];
// Last setup the vertical contraints other wise they will end up in a random place
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_label1]-[_label2]-[_label3]"
options:0
metrics:nil
views:_viewsDictionary];
[self addConstraints:constraints];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
@end
.