2017-08-12 69 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

解决了我所有的问题,谢谢! –

相关问题