I am hopelessly stuck and I would appreciate a pointer.
We are trying to create a view controller, including several views that are subclasses of UIView. Everything works "well", except for the fact that we need to either manually initialize the view or call awakeFromNib manually again, which is not allowed.
Here is the problem ...
UIView subclass header file:
The main file of the UiView subclass:
#import "introView.h" @interface introView () @end @implementation introView -(id)init { NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"introView" owner:self options:nil]; id mainView = [subviewArray objectAtIndex:0]; return mainView; } - (void) awakeFromNib { [super awakeFromNib]; [self initialize]; [self addSubview:self.view]; } -(void)initialize { NSLog(@"title: %@", self.title); self.titleLabel.text = self.title; }
Then we initialize the view from the view controller:
introView *view = [[introView alloc]init]; view.title = @"Test"; [self addSubview:view];
Here's the problem - just calling this view, the view is displayed correctly, but the header is NULL;
[43605:1957090] title: (null)
If, however, we call awakeFromNib again, then the view is correctly initialized
In the view controller:
introView *view = [[introView alloc]init]; view.title = @"Test; [self addSubview:view]; [view awakeFromNib];
Then it works:
2014-11-21 09:33:03.500 Test[43706:1972060] title: (null) 2014-11-21 09:33:03.500 Test[43706:1972060] title: Test
Alternatively, if I make the initialize method public and call that it works after initialization. But it defeats the goal in my eyes ...
In the view controller:
introView *view = [[introView alloc]init]; view.title = @"Test; [self addSubview:view]; [view initialize]; //calling the method directly...
It seems to me that we somehow fulfill the condition when the view is not ready yet, but then it works in the second attempt (although the call to awakeFromNib is illegal)
Again the outputs are configured correctly, the owner of the file is set ... he just needs two calls to awakeFromNib.
Any help is appreciated.
---------------- UPDATE ------------------
Thanks guys, I appreciate the pointer. I implemented the initializer as indicated, but I have the same problem. In addition, I used the GitHub example as a pure example and tried to assign a variable to this view, and even this shows the same behavior. So I'm starting to think that I'm doing something wrong elsewhere. See here:
// // SubClassView.h // CustomView // // Created by Paul Solt on 4/28/14. // Copyright (c) 2014 Paul Solt. All rights reserved. // #import <UIKit/UIKit.h>
SubclassView.m
// // SubClassView.m // CustomView // // Created by Paul Solt on 4/28/14. // Copyright (c) 2014 Paul Solt. All rights reserved. // #import "SubClassView.h" @interface SubClassView() @property (weak, nonatomic) IBOutlet UILabel *label; @property (weak, nonatomic) IBOutlet UISwitch *onSwitch; @end @implementation SubClassView // Note: You can customize the behavior after calling the super method // Called when loading programatically - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if(self) { // Call a common method to setup gesture and state of UIView [self setup]; } return self; } // Called when loading from embedded .xib UIView - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if(self) { // Call a common method to setup gesture and state of UIView [self setup]; } return self; } - (void)setup { // Add a gesture to show that touch input works on full bounds of UIView NSLog(@"%@", self.title); UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; [self addGestureRecognizer:panGesture]; } - (void)handlePanGesture:(UIPanGestureRecognizer *)gesture { NSLog(@"Pan: %@", NSStringFromCGPoint([gesture locationInView:gesture.view])); } - (IBAction)switchChanged:(UISwitch *)sender { NSLog(@"Switch: %d", sender.on); } @end
View controller class
// // ViewController.m // CustomView // // Created by Paul Solt on 4/28/14. // Copyright (c) 2014 Paul Solt. All rights reserved. // #import "ViewController.h" #import "SubClassView.h" #import "LabelMadness.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Add a custom view programmatically (position using 1/2 width and height) SubClassView *oneView = [[SubClassView alloc] init]; oneView.center = CGPointMake(80 + 80, 282 + 40); oneView.backgroundColor = [UIColor blueColor]; oneView.title = @"Test2"; [self.view addSubview:oneView]; } @end
------- CONCLUSION -----
2014-11-21 11:49:38.893 CustomView[45653:2123668] LabelMadness.initWithFrame: 2014-11-21 11:49:38.893 CustomView[45653:2123668] (null)
What am I doing wrong here?