UIView drawRect vs initWithFrame

11,195

Solution 1

@tonklon is spot on. Additionally, the usual pattern is to have your custom initialization code in a third method, such as -sharedInit, which is called after the appropriate super initializer:

- (id)sharedInit {
    // do whatever, possibly releasing self on error and returning nil
    return self;
}

- (id)initWithFrame: (CGRect)frame {
    self = [super initWithFrame: frame];
    if (self) {
        self = [self sharedInit];
    }
    return self;
}

- (id)initWithCoder: (NSCoder *)aDecoder {
    self = [super initWithDecoder: aDecoder];
    if (self) {
        self = [self sharedInit];
    }
    return self;
}

Solution 2

I bet the view is loaded from a nib file? Just use the same code to add your subviews in initWithCoder:

UIView Class Reference:

If you use Interface Builder to design your interface, this method is not called when your view objects are subsequently loaded from the nib file. Objects in a nib file are reconstituted and then initialized using their initWithCoder: method, which modifies the attributes of the view to match the attributes stored in the nib file. For detailed information about how views are loaded from a nib file, see Resource Programming Guide.

Share:
11,195
John Smith
Author by

John Smith

Updated on June 04, 2022

Comments

  • John Smith
    John Smith almost 2 years

    I have a UIView which has several buttons added to it as subviews. Currently I have the buttons in drawRect:, which I have heard is a bad idea because drawRect can be called several times. I tried to move these UIButtons to initWithFrame, but they just don't get drawn. How should I fix this?

    I am not using interface builder, so there are no NIB files present. The initWithFrame is called. I checked by adding an NSLog(...), and my NSMutableArrays are being properly initialized.

    My initWitFrame: code currently has very little. It is

    - (id)initWithFrame:(CGRect)frame 
    {
        if (self = [super initWithFrame:frame]) 
        {
            results = [[NSMutableArray alloc] init];
            inputs = [[NSMutableArray alloc] init];
            format = [[NSDateFormatter alloc] init];
            [format setDateFormat:@"EEE, MMM dd, yyyy"];
            renc =[[RenameController alloc] init];
        }
        return self;
    }
    

    I have tried to add a textlabel like the following

    #define BOX_WIDTH 155.0
    #define BOX_OFFSET 45.00
    #define ROW_HEIGHT 27
    
    - (id)initWithFrame:(CGRect)frame 
    {
        if (self = [super initWithFrame:frame]) 
        {
            results = [[NSMutableArray alloc] init];
            inputs = [[NSMutableArray alloc] init];
            format = [[NSDateFormatter alloc] init];
            [format setDateFormat:@"EEE, MMM dd, yyyy"];
            renc =[[RenameController alloc] init];
    
            double row=0.0;
            [self makelabel:@"Start" at:CGRectMake(0, row, BOX_OFFSET, ROW_HEIGHT)];
        }
        return self;
    }
    
    -(void) makelabel:(NSString *) str at:(CGRect) rect
    {
        UILabel *title = [[UILabel alloc] initWithFrame:rect];
        title.text = str;
        title.textAlignment = UITextAlignmentLeft;
        title.textColor = [UIColor blackColor];
        title.backgroundColor = [UIColor clearColor];
        title.font = [UIFont boldSystemFontOfSize:FONT_SIZE];
        [self addSubview:title];
        [title release];
    }
    
  • John Smith
    John Smith over 13 years
    Sorry, no interface builder in this house!