簡體   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