简体   繁体   中英

Working on custom component: subclass UIView or UIViewController?

I'm working on a custom implementation of UISegmentedControl. I'd like to create a component that able to receive config data and from which obtain a custom View similar to UISegmentedControl.

I started subclassing a UIView and i can create a custom UISegmentedControl with this code:

CustomSegment *segment = [[CustomSegment alloc] 
                         initWithTitles:[NSArray arrayWithObjects:@"one",@"two",nil]];
[self.window addSubview:segment];

But now i'd like to improve my class and add some more customizable parameters to it. For example i'd like add a custom separators, define the button fonts and so on... here my doubt: Is it better to work on a UIView subClass or you suggest me to subclass a UIViewController, where i can manage View hierarchy in method like - (void)loadView and -(void)viewDidLoad ?

In a simple UIView subclass, when i launch the custom init method, i setup immediately subviews... while using a UIViewController i can call custom init and define how my subview is builded into -(void)loadView.

Don't use an UIViewController, just extend the UIView class like you did and keep extending its functionality.

Remember to save a pointer to each subview you add (ie buttons) in order to be able to access them later.

Define custom setters, for example, a custom setter for changing a button label title would be:

- (void) setButton1Title:(NSString*)str forState:(UIControlState)state{
     //You can add some control here
     if ([str length] > 20) return;
     [_button1 setTitle:str forState:state]; //_button1 is my reference to the button
}

And so on. Don't provide direct access to your subviews, use methods instead.

Also, you can use "layoutSubviews" method to define how your views are going to be displayed in your custom view.

Hope it helps you.


Edit: In your case, I don't see why using lauoutSubviews method but I want to show you what I was trying to say.

Lets say that for example I need to create an UIView class to represent a "Contact" object in my application.

This is what I would do:

@interface ContactView : UIView{
     UILabel*  _nameLabel;
     UILabel*  _ageLabel;
     Contact*  _contact;
}
@property (retain) Contact* contact;

@end

@implementation ContactView

@synthetize contact = _contact;

-(id)initWithContact:(Contact*)c{
    self = [super init];
    if (self) {
        _nameLabel = [[UILabel alloc] init];
        _nameLabel.frame = CGRectZero;
        [self addSubview:_nameLabel];
        [_nameLabel release];

        _ageLabel = [[UILabel alloc] init];
        _ageLabel.frame = CGRectZero;
        [self addSubview:_ageLabel];
        [_ageLabel release];

        self.contact = c;
    }
}

- (void) layoutSubviews{
    [super layoutSubviews];

    _nameLabel.frame = CGRectMake(0.0f, 0.0f, 200.0f, 25.0f);
    _ageLabel.frame = CGRectMake(0.0f, 25.0f, 200.0f, 25.0f);

    if (self.contact){
        _nameLabel.text = self.contact.name;
        _ageLabel.text = self.contact.age;
    }else{
        _nameLabel.text = @"Unavailable";
        _ageLabel.text = @"Unavailable";
    }
}

- (void) setContact:(Contact*)c{
    self.contact = c;
    [self layoutSubviews];
}

@end

Check out how the "layoutSubiews" is used to set the correct frame and data to the labels. Usually, I use it a lot when creating custom UITableViewCells where you have to reuse the view.

Let me know if I'm being confusing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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