繁体   English   中英

以编程方式设计目标视图-C

[英]programmatically Design a View in objective - C

我的项目是设计一个具有多个标签,图像,textField的视图,而没有故事板或Nib。 我是否需要手动分配并将每件事添加到视图中? 我认为这太过分了,但是我不知道该如何做。 例:

UILabel *firstLabel =[UILabel alloc] init];
firstLabel.frame  = (0,x,20,10) ;
firstLabel.text = ...;
firstLabel.font = ...;
firstLabel.textColor = ...;
.................
[self.view addSubView:firstLabel];

UILabel *secondLabel =[UIlabel alloc] init];
secondLabel.frame = (0,y,20,10);    
secondLabel.text = ...;
secondLabel.font = ...;
secondLabel.textColor = ...;
.................
[self.view addSubView:secondLabel];

UILabel *thirdLabel =[UIlabel alloc] init];
    thirdLabel.frame = (0,z,20,10);    
    thirdLabel.text = ...;
    thirdLabel.font = ...;
   thirdLabel.textColor = ...;
    .................
    [self.view addSubView:thirdLabel];

我应该将它们全部放在viewDidLoadloadView还是init方法中吗?

或者我只需要为CreatLabel创建一个方法,然后一次又一次地使用它? 怎么做?

如果我正确理解您的要求,请问如何将DRY(不要重复自己)应用于此代码。

«更多两个–使用一个» Edsger W. Dijkstra

要么

«更多的两个-使用枚举» vikingosegundo

- (void)viewDidLoad { // or loadView, see Rob's answer
    [super viewDidLoad];

    NSArray *properties= @[@{@"color": [UIColor orangeColor], @"text": @"Ceterum censeo"},
                          @{@"color": [UIColor cyanColor], @"text": @"Carthaginem esse"},
                          @{@"color": [UIColor purpleColor], @"text": @"delendam"}];

    [properties enumerateObjectsUsingBlock:^(NSDictionary *properties, NSUInteger idx, BOOL *stop) {
          UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(0, (idx + 1) * 20, 200, 20)];
          l.backgroundColor = properties[@"color"];
          l.text = properties[@"text"];
          l.font= [UIFont italicSystemFontOfSize:12];
          [self.view addSubview:l];
      }];
}

好的,为什么我在这里更喜欢这种基于块的枚举?
因为它有一个变种保护器,可以免费为我提供框架所需的正确索引。

AC for -loop for (int idx = 0; idx < [properties count]; ++idx)给了我正确的索引,但是我必须包括一条额外的语句来获取对象NSDictionary *property = properties[idx]; 并且由于它没有突变防护:可能会在迭代过程中对其进行更改,这可能会导致不良后果。

for(NSDictionary *property in properties)的快速枚举具有这样的突变防护,并且比块枚举的枚举甚至更快。 但这有一个很大的缺点,即如果我需要索引,则必须调用NSUIndex idx = [properties indexForObject:property]; 导致二次运行时性能,而不是线性:再见,速度优势。 更糟糕的是:如果一个数组包含相同的对象,它将只能反复找到第一个对象,这是创建错误数据的好机会。

根据代码量的不同,将其移到辅助方法中可能会很有用,但这更多是关于品味的。


由于您的问题最后是关于可读性的,所以我想分享另一个趣味:我喜欢将对象创建封装到一个不同的范围中:

通过使用隐式块

UILabel *label = ^{
    UILabel *l =[[UILabel alloc] initWithFrame:CGRectMake(0, (idx + 1) * 20, 200, 20)];
    l.backgroundColor = properties[@"color"];
    l.text = properties[@"text"];
    l.font= [UIFont italicSystemFontOfSize:12];
    return l;
}();
[self.view addSubview:label];

或陈述式

UILabel *label = ({
    UILabel *l =[[UILabel alloc] initWithFrame:CGRectMake(0, (idx + 1) * 20, 200, 20)];
    l.backgroundColor = properties[@"color"];
    l.text = properties[@"text"];
    l.font= [UIFont italicSystemFontOfSize:12];
    l;
});
[self.view addSubview:label];

如果要以编程方式从头开始创建视图,则可以在loadView (请参阅以编程方式创建视图 。)但是,如果您具有用于顶层视图的NIB / storyboard,而您仅添加了子视图,则可以在viewDidLoad

关于创建一堆标签,是的,您可以使用子例程。 或者,假设有一个规则的模式来指示这些位置,那么您甚至可以使用for循环,在其中增加y坐标或构建约束。 (您可以将对这些视图的引用保存在数组中,也可以使用tag值来跟踪它们。)但是,您可以这样做,是的,您希望减少重复编写的代码量(从维护的角度简化工作寿命) ,如果没有别的)。

可以放入ViewDidLoad(),但如果标签数量很多,请使用自定义方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM