How to Call awakeFromNib in mainViewController.m - objective-c

I have an xib file containing a custom cell. I'm trying to access the height of an object created in customCell.m.
Here is my code:
customCell.m
- (void)awakeFromNib
{
self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 200)];
[self.label setText:#"This is a label"];
[self.myView addSubview:self.label];
NSLog(#"%f", self.label.frame.size.height); // Results: 200.0000
}
mainViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
customCell *cellVC = [[cutsomCell alloc] init];
NSLog(#"%f, %f", cellVC.label.frame.size.height); // Results: 0.0000
}

awakeFromNib is called when all file owners outlets and properties are set. Things are not wired up (in terms of frames/layout) in viewDidLoad.
awakeFromNib is called after viewDidLoad, that is why you see the difference.

Sorry, this doesn't work. You are creating your customCell via alloc/init in code. AwakeFromNib is only called for objects defined in a nib file.
You probably need to define your customCell in a separate nib file, and load that nib file through + (BOOL)loadNibNamed:(NSString *)aNibName owner:(id)owner or similar.

Related

UIView Subclass backed by xib with Size Classes wrong frame

I am working on a project for iOS 7.0+ with a storyboard, using Size Classes with AutoLayout and I'm using a UIView subclass backed by a xib file of the same name.
What I'am trying to do is I'am instantiating a UIView from xib programmatically and adding it to a ViewController from a Storyboard. This ViewController has AutoLayout up and running but the UIView I am adding doesn't respect the frame of the ViewController.
I'm instantiating my UIView subclass like this:
tabBarView = [[SHDTabBarView alloc] initWithFrame:CGRectMake(0, self.view.height-50, self.view.width, 50)];
[self.view addSubview:tabBarView];
And inside the subclass I'm using a set up of creating a UIView IBOutlet called container to instantiate it form code like this:
-(id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self == nil) return nil;
[self initalizeSubviews];
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self == nil) return nil;
[self initalizeSubviews];
return self;
}
-(void)initalizeSubviews{
NSString *nibName = NSStringFromClass([self class]);
UINib *nib = [UINib nibWithNibName:nibName bundle:nil];
[nib instantiateWithOwner:self options:nil];
//Add the view loaded from the nib into self.
[self addSubview:self.container];
}
This is how my xib looks in the Interface Builder (notice the width of the canvas is 320 px):
And that's how it looks on the iPhone 6 (notice how it's getting cut off from the right side):
I've tried to use a multitude of solutions, including doing it all in code with an open-source solution PureLayout, using a manual constraint set up, etc.
None of my findings seem to work right. Ideally, I want to set up everything in Interface Builder, then just add the view to the superview of the ViewController with according frame and let AutoLayout do its magic.
How should I approach this task? Any advices are more than welcome.
Try to set the frame of your subview in the viewDidLayoutSubviews(). Looks like you init your subview before view fully layouted

Passing data to a UIView - failure

I have a strange problem that I've never encountered before,
I have data in my viewController that I want to display in a UIView.
It's an iPad App which involve a SplitView Controller, when I click on an element within the table view (masterView) it execute a function in my detailViewController (via a protocol).
A function is executed which launch a UIView and send data to it:
myController:
- (void)SelectionChanged:(DocumentInfo*)document_info withDocu:(Document *)document{
DocumentView *viewDoc=[[DocumentView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
viewDoc.doc=document;
viewDoc.doc_info=document_info;
[viewDoc setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:viewDoc];
}
DocumentView.h
#import <UIKit/UIKit.h>
#import "Document.h"
#import "DocumentInfo.h"
#class Document;
#class DocumentInfo;
#interface DocumentView : UIView
#property(strong,nonatomic) Document *doc;
#property(strong,nonatomic) DocumentInfo *doc_info;
#end
DocumentView.m
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UILabel *titreDoc=[[UILabel alloc] initWithFrame:CGRectMake(20, 32, 339, 21)];
titreDoc.textColor = [self makeColorRGB_RED:66 GREEN:101 BLUE:149];
titreDoc.font = [UIFont fontWithName:#"System" size:(24.0)];
[self addSubview:titreDoc];
NSLog(#"%# - %#",doc,doc_info);
titreDoc.text=#"Nouveau Document";
}
return self;
}
My view is well displayed (I mean the label appear) but impossible to get the data which would have been passed to it... (the NSLog print (null) (null) )
Anybody know the reason why?
The problem seems pretty straight forward. You initialize your view (which means that you run - (id)initWithFrame:(CGRect)frame) and after that you're setting the data, so it's normal that you see null values into your init method because the ivars have not being set yet. What you could do is to modify your init method in order to construct your view taking into account these ivars. Something like this perhaps:
- (id)initWithFrame:(CGRect)frame doc:(Document *)doc docInfo:(DocumentInfo *)docInfo;
ps. If you choose to make your custom init method do not forget to call the designated initializer (-initWithFrame:) before any customization.
The reason the NSLog prints null is because the doc and doc_info are nil when the initWithFrame method is called. The doc and doc_info properties are set after the initWithFrame method is called in selectionChanged: method. Add the NSLog function after line 3 in selectionChanged method like this:
- (void)SelectionChanged:(DocumentInfo*)document_info withDocu:(Document *)document{
DocumentView *viewDoc=[[DocumentView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
viewDoc.doc=document;
viewDoc.doc_info=document_info;
NSLog(#"%# - %#",doc,doc_info);
[viewDoc setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:viewDoc];
}

programmatically created table does not work

I created a UITableView programmatically, but none of its methods were called. I must have missed something:
- (void)viewDidLoad
{
[super viewDidLoad];
...
self.transactionView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, CARD_VIEW_Y, 320.0, CARD_VIEW_H)];
self.transactionView.delegate = self;
[self.view addSubview:self.transactionView];
You need to wire both the delegate AND the dataSource of the tableview. UITableViewDataSource provides the methods to fill the actual table with data.

Create subview on awakeFromNib

I'm trying to create a NSImageView programmatically as a subview of another NSImageView when awakeFromNib is called.
My code is as follows (Fader is defined in MyImageView.h):
#implementation MyImageView
- (void)awakeFromNib {
Fader = [NSImageView initWithFrame: [self frame]];
}
I get the warning message "NSImageView may not respong to +initWithFrame". When I build, the app simply frizzes without showing anything, and I have to "force quit".
What am I doing wrong?
You’ve forgotten to send +alloc in order to allocate the object. Change that line to:
Fader = [[NSImageView alloc] initWithFrame: [self frame]];

Subviews not showing up in UIView class

I'm trying to lay out some images in code using addSubview, and they are not showing up.
I created a class (myUIView) that subclasses UIView, and then changed the class of the nib file in IB to be myUIView.
Then I put in the following code, but am still getting a blank grey screen.
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
[self setupSubviews];
}
return self;
}
- (void)setupSubviews
{
self.backgroundColor = [UIColor blackColor];
UIImageView *black = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"black.png"]];
black.center = self.center;
black.opaque = YES;
[self addSubview:black];
[black release];
}
yes, just implement initWithCoder.
initWithFrame is called when a UIView is created dynamically, from code.
a view that is loaded from a .nib file is always instantiated using initWithCoder, the coder takes care of reading the settings from the .nib file
i took the habit to do the initialization in a separate method, implementing both initWithCode and initWithFrame (and my own initialization methods when required)
try implementing initWithCoder: sometimes I've had trouble with IB and initWithFrame:
or at least add a logging call to see if your init method is executed