2017-08-12 103 views
0

我有從UIView繼承的自定義視圖。現在我想添加一個UISegmentedControl作爲它的子視圖。 所以第一個問題是:UISegmentedControl的屬性應該弱還是強? (使用IBOutlets我知道Apple自2015年起推薦使用強大的功能)。 第二個問題是我在哪裏初始化它並設置其佈局。據我所知,我不應該在drawRect:方法中做到這一點。如果它在initWithFrame初始化:方法,添加作爲一個子視圖到我的自定義視圖,然後它的佈局在layoutSubviews像這樣設置:如何初始化並將子視圖添加到自定義UIView?

- (instancetype)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 

    if (self) { 
     NSArray *options = @[@"option1", @"option2", @"option3"]; 
     self.segmentedControl = [[UISegmentedControl alloc] initWithItems:options]; 
     [self.segmentedControl addTarget:self action:@selector(someAction:) forControlEvents:UIControlEventValueChanged]; 

     [self addSubview:self.segmentedControl]; 
    } 

    return self; 
} 

- (void)layoutSubviews { 
    [super layoutSubviews]; 

    CGRect segmentedControlFrame = CGRectMake(self.bounds.size.width/4.0, 50, self.bounds.size.width/2.0, 30); 
    self.segmentedControl.frame = segmentedControlFrame; 
    self.segmentedControl.tintColor = [UIColor blackColor]; 
    [self.segmentedControl setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]} forState:UIControlStateSelected]; 
} 

或只是做這一切在layoutSubviews:方法:

- (void)layoutSubviews { 
    NSArray *options = @[@"option1", @"option2", @"option3"]; 
    self.segmentedControl = [[UISegmentedControl alloc] initWithItems:options]; 

    CGRect segmentedControlFrame = CGRectMake(self.bounds.size.width/4.0, 50, self.bounds.size.width/2.0, 30); 
    segmentedControl.frame = segmentedControlFrame; 
    segmentedControl.tintColor = [UIColor blackColor]; 
    [segmentedControl setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]} forState:UIControlStateSelected]; 
    [segmentedControl addTarget:self action:@selector(someAction:) forControlEvents:UIControlEventValueChanged]; 

    [self addSubview:segmentedControl]; 
} 

回答

0

如果您的視圖如果未包含在分層結構中,那麼您應該使用strong。當分段控件始終屬於層次結構的一部分時,可以使用weak,但必須將其保留爲強引用,直到將其添加到層次結構中。在你的第一個代碼段,你必須使用本地(強)變量,其持有的控制:

- (instancetype)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 

    if (self) { 
     NSArray *options = @[@"option1", @"option2", @"option3"]; 
     UISegmentedControl *control = [[UISegmentedControl alloc] initWithItems:options]; 

     [control addTarget:self action:@selector(someAction:) forControlEvents:UIControlEventValueChanged]; 

     [self addSubview:control]; // By now the view keeps the control 
     self.segmentedControl = control; 
    } 
    return self; 
} 

弱引用的優點是,它會自動重置了,如果您從層次結構中的控制。這可以幫助你保持較小的存儲量。

對於佈局,您應該更喜歡自動佈局約束。自動調整也是可能的(無論如何請看translatesAutoresizingMaskInotConstraints)。 layoutSubviews不應該將該段添加到視圖中,因爲它會多次調用。

+0

謝謝!如果,例如,我有一個UIViewController,在它的loadView:方法中,我將自定義視圖分配給視圖控制器視圖(self.view = customView)。我決定在這個視圖控制器中添加UISegmentedControl作爲子視圖,而不是在自定義視圖中。我應該在哪裏做?在viewDidLoad:方法?那麼只需在方法中創建一個UISegmentedControl作爲局部變量,然後將其添加爲子視圖呢?是否比創造它作爲一種財產更好? (但其他方法,如果我想訪問它,我需要通過self.view.subviews)。 –

+0

一般而言'viewDidLoad'是添加視圖的好地方。您稍後需要訪問視圖時只需要屬性(例如:'viewWillAppear:',操作方法)。遍歷層次結構是可能的,但並不好玩。 – clemens

+0

解決了我所有的問題,謝謝! –

相關問題