2

I have made a simple subclass of UIView which has a few subviews but its breaking for a reason I can't see.

In my storyboard view controller I have added a UIView and made it the shape I want it, and added my custom class to it. The contents of my subclass is below:

@implementation PersonDetailCell

@synthesize button, requiredMarker, textField;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code

    }
    return self;
}

-(void)layoutSubviews
{
    [self setBackgroundColor:[UIColor colorWithRed:87.0f/255.0f green:153.0f/255.0f blue:191.0f/255.0f alpha:1.0f]];

    textField = [[DetailTextField alloc] initWithFrame:CGRectMake(10, 0, self.frame.size.width -20, self.frame.size.height)];
    [textField setFont:[UIFont fontWithName:@"Helvetica" size:14.0f]];
    [textField setTextColor:[UIColor whiteColor]];
    [textField setHidden:YES];
    [self addSubview:textField];

    button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [button setHidden:YES];
    [self addSubview:button];

    requiredMarker = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 4, 22)];
    [requiredMarker setBackgroundColor:[UIColor redColor]];
    [requiredMarker setHidden:YES];
    [self addSubview:requiredMarker];
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

@end

Then in my view controller code I have imported my subclass and hooked up an IBOutlet of it to my view in my storyboard. In my viewDidLoad of my view controller I also try setting background colour of this view but nothing happens.

All of my code runs without crashing, but my issues:

  1. I can't set the background colour from my view controller, (or any other properties for that matter).

  2. When I run the app, the height is more than that I set in my storyboard (width is fine), but I change the height of the view nowhere.

Any ideas? Am i using the wrong approach somehow?

Thanks.

Josh Kahane
  • 15,834
  • 40
  • 127
  • 241
  • Hmm. It's going to get the initWithCoder: init from storyboard, but it doesn't look like you're using that init anyway. Have you tried logging the value of the outlet in your vc's viewDidLoad? Let's make sure that's not nil. Also, breakpoint in layoutSubviews might be a good diagnostic, too. – danh Nov 08 '12 at 01:04
  • Regarding the height, check the autosizing masks in storyboard and make sure that the view you added and shaped has no adjustable height setting. – danh Nov 08 '12 at 01:06
  • Show the code in viewDidLoad where you try to set the background color. – rdelmar Nov 08 '12 at 02:46
  • I'll do some additional debugging as suggested when I return to my computer and feedback here. As for the viewDidLoad code, I simply call: [customView setBackgroundColor:[UIColor blueColor]]; customView being the variable name for the UIView subclass I made and hooked up in my storyboard. – Josh Kahane Nov 08 '12 at 03:29
  • Ok I have fixed the size issue, but still my subviews aren't to be seen. I've logged the object in the viewDidLoad of my view controller and apparently its frame is 0, 0, 0, 0. Despite putting it in my storyboard. – Josh Kahane Nov 08 '12 at 11:34
  • Ok, seems if I don't add subviews via layoutSubviews method, then setting properties like background colour from my view controller works fine. Where should I be adding the subviews in my subclass? – Josh Kahane Nov 08 '12 at 11:43

2 Answers2

1

If it is a table cell, then the class should be extending UITableViewCell. Buttons and textfields can be added on the storyboard - then you can use struts and springs (Size Inspector pane) to ensure the view resizes properly. I don't think layoutSubviews should be used for adding new UI elements (maybe for resizing if you need to do it manually).

kat
  • 517
  • 4
  • 7
  • It's not a table view cell, just a custom view I've made. If I shouldn't be adding sub views in layoutSubviews, where should I? – Josh Kahane Nov 08 '12 at 02:21
  • Try overriding loadView or viewDidLoad in the controller (lifecycle details here http://stackoverflow.com/questions/5562938/looking-to-understand-the-ios-uiview-lifecycle). Although at that point the controller is doing the heavy lifting. You may try initWithFrame in the view, but I am not sure whether that's good practice. – kat Nov 08 '12 at 05:29
  • Apple docs: http://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html – kat Nov 08 '12 at 05:34
  • 1
    So your suggesting I add the subviews to my custom UIView from my UIViewController? Surely this defeats the point of having a UIView subclass setup if I have to add all my objects in the view controller? Or am I missing something? – Josh Kahane Nov 08 '12 at 11:19
0

Here is some working code:

@interface ChildView()
@property (strong, nonatomic) UITextField *textField;
@property (strong, nonatomic) UIButton *button;
@property (strong, nonatomic) UIImageView *requiredMarker;
@end

@implementation ChildView

@synthesize textField= _textField;
@synthesize button = _button;
@synthesize requiredMarker = _requiredMarker;

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self)
    {
        [self setBackgroundColor:[UIColor colorWithRed:87.0f/255.0f green:153.0f/255.0f blue:191.0f/255.0f alpha:1.0f]];

        self.textField = [[UITextField alloc] init];
        [self.textField setFont:[UIFont fontWithName:@"Helvetica" size:14.0f]];
        [self.textField setTextColor:[UIColor whiteColor]];
        self.textField.text = @"Test text";
        [self addSubview:self.textField];

        self.button = [[UIButton alloc] init];
        self.button.backgroundColor = [UIColor greenColor];
        [self addSubview:self.button];

        self.requiredMarker = [[UIImageView alloc] init];
        [self.requiredMarker setBackgroundColor:[UIColor redColor]];
        [self addSubview:self.requiredMarker];
    }
    return self;
}

-(void)layoutSubviews
{
    CGSize hostSize = self.frame.size;
    float length = 22;
    self.textField.frame = CGRectMake(10, length, hostSize.width, hostSize.height-length);
    self.button.frame = CGRectMake(0, 0, hostSize.width, length);
    self.requiredMarker.frame = CGRectMake(0, 0, 4, length);
}

@end
kat
  • 517
  • 4
  • 7