UITableViewController Xib not being used in iOS5 (working in iOS 6) - ios

I have several ViewControllers which subclass UITableViewController and have a Xib file where I set the TableViews appearances (style, colours etc) and add a header and footer.
There xib files do not appear to be getting loaded on iOS 5. On iOS 6 the xib is loaded and the view looks as expected.
iOS 6
iOS 5
Xib - Interface Builder
Any ideas?

Turns out that prior to iOS 5 the UITableViewController designated initialiser did not load the Nib. This changed with iOS 6 and it now checks for a Nib.
To make the app work with both version I have made my designated initialiser call
self = [super initWithNibName:#"Nib Name" bundle:nil];

Thank.
It's OK for Me
i add a method 'initWithMyNib'
i replace 'initWithStyle' with 'initWithMyNib'
(id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self)
{
// Custom initialization
}
return self;
}
(id)initWithMyNib:(NSString*)strNibName
{
self = [super initWithNibName:strNibName bundle:nil];
if (self)
{
// Custom initialization
}
return self;
}

Related

UICollectionView custom class not work

I'm new in iOS programming and I apologize for the lack of experience.
I have a storyboard with UITabViewController and 2 tabs ( call it First and Second as example ). On "First" tab ( custom class - CFirstTabController ) I placed Collection View with custom class - CCollectionViewController. In it I placed Collection View Cell, added custom class to it - all as need.
Here class CCollectionViewController:
#import "CCollectionViewController.h"
#import "CSomeClassAsDataSource.h"
#implementation CCollectionViewController
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self setDataSource:[CSomeClassAsDataSource init]];
}
return self;
}
- (void)reloadData
{
[super reloadData];
}
#end
And here is a problem: I want use other class as dataSource (CSomeClassAsDataSource implements protocol for it ), but I can't set it! Methods of this class not invoked. And I do not know why. I'm registered class CCollectionViewController as "Custom class" for my Controller View, but seems Xcode ignores it.
Your dataSource initialisation seems to be wrong as you've missed the alloc. Should be:
self.dataSource = [CSomeClassAsDataSource alloc] init];

Change the UITableViewStyle for different iOS versions

I have to tableview designs for ios7/6 - in ios6 I need to implement a tableview grouped style and in ios7 I need a plain one. So In storyboards I change the style to plain and in viewDidLoad of the subclass of UITableViewController I have something like this:
if (!IS_OS_7_OR_LATER) {
self = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];
}
But it doesn't work. I tried to use initWithCoder method but can't get the good result. Any help?
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)
{
bool isLowerOrEqualToSix = (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1);
if (isLowerOrEqualToSix) { // iOS 6 or lower
[super initWithFrame:frame style:UITableViewStyleGrouped];
} else { // iOS 7 or higher
[super initWithFrame:frame style:UITableViewStylePlain];
}
}
This is what you need.
Try subclassing UITableView, and override this method:
-(id)initWithFrame:(CGRect)frame style:(UITableViewStyle)
{
if (!IS_OS_7_OR_LATER) {
[super initWithFrame:frame style:UITableViewStyleGrouped];
} else
[super initWithFrame:frame style:UITableViewStylePlain];
}
Then, on Interface Builder, set the class of your tableView to be the derived class you just created.
As stated in tableview class reference the style property has to be set at initialization. It cannot be changed after this. In code you would do this with if statement checking ios version and initializing with appropriate style. Using storyboards follow this link How to switch to different Storyboard for iPhone 5?

Function that is called when UILabel initializes

I am trying to subclass UILabel. The first try involves that my custom UILabel simply sets the property adjustsFontSizeToFitWidth to YES. The problem is that I am new to iOS programming and unsure about where to put this code. I tried the code below but they are never called.
- (id)initWithFrame:(CGRect)frame
{
NSLog(#"init custom label");
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.adjustsFontSizeToFitWidth=YES;
}
return self;
}
- (id)init
{
NSLog(#"init custom label");
self = [super init];
if (self) {
// Initialization code here.
self.adjustsFontSizeToFitWidth=YES;
}
return self;
}
I got it to work by using:
lblCustom = [lblCustom init];
But is there someway I can get this call to be called automatically?
When a label is used in interface builder is then the coded use the NSCoder protocol:
- (id)initWithCoder:(NSCoder *)aDecoder
{
NSLog(#"init custom label");
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code here.
self.adjustsFontSizeToFitWidth=YES;
}
return self;
}
What I do, is create one method to setup my custom UI object and let all the init call this method.
I would personally stay away from initWithCoder: and instead use awakeFromNib instead. Here is why (Apple UIKit Documentation):
The nib-loading infrastructure sends an awakeFromNib message to each
object recreated from a nib archive, but only after all the objects in
the archive have been loaded and initialized. When an object receives
an awakeFromNib message, it is guaranteed to have all its outlet and
action connections already established.
I have a variety of UI subclasses in my program and here is the solution I came up in my BaseLabel class.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
// We were not loaded from a NIB
[self labelDidLoad:NO];
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
// We were loaded from a NIB
[self labelDidLoad:YES];
}
- (void)labelDidLoad:(BOOL)loadedFromNib
{
// Do some initialization here...
}
Now all of my subclasses simply override {type}didLoad:(BOOL)loadedFromNib.
For example buttonDidLoad:, textFieldDidLoad:, and tableViewDidLoad: (you get the idea).
Calling only init on an UIView is the same as calling initWithFrame: with a zero-rect. So you should override initWithFrame or initWithCoder if you are using nib-files.

Custom UIView with custom initialization doesn't work

I'm developing an iOS app with latest SDK.
I have created a class that inherits from UIView and I have to do some initialization every time the class is instantiated.
I have to call a method called setUpVars: but I don't know where to send a message to that method:
- (id)initWithFrame:(CGRect)frame;
- (id)initWithCoder:(NSCoder*)aDecoder;
This class can be used with a custom xib, or added to a Storyboard, so I need to be sure that that method will be called on every case.
- (void)setUpVars
{
_preferenceKey = #"";
_preferenceStatus = NO;
_isDown = NO;
}
Where do I have to add [self setUpVars];?
Essentially you will be wanting to cover both cases
- (id)initWithFrame:(CGRect)frame;
{
self = [super initWithFrame:frame];
if (self) {
[self setUpVars];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder;
{
self = [super initWithCoder:aDecoder];
if (self) {
[self setUpVars];
}
return self;
}
I think that you need to send this message from each method, also do not forget about awakeFromNib method.
You can create BOOL variable, something like isAlreadySetup and set it to YES in setUpVars method.
Docs Says
awakeFromNib
Prepares the receiver for service after it has been loaded from an
Interface Builder archive, or nib file.
- (void)awakeFromNib
{
[self setUpVars];
}
If you use Interface Builder to design your interface, initWithFrame: is not called when your view objects are subsequently loaded from the nib file. Instead initWithCoder gets called. So you can initialize your variables in both methods if you prefer a generic way. Works in both case
I tend to think you should call this method from the -(void)viewDidLoad method of the controller in charge

How to initialize UITableView? Both from XIB and programmatically?

I have a simple request that I have spent much time on (embarrassingly)..
I have sub-classed a UITableView to add some functionality. These new features require things like NSMutableSet which require allocation/initialization.
I have put my object's initialization routine in
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
which I understood from the apple docs to correct - but this doesn't get called (determined by break-pointing on the code).
I am using IB, and have dragged a UITableView onto the view, and changed it's class to my new sub-class. There is no UITableViewController.
I have also tried:
- (void)loadView {
- (id)init {
- (id)initWithFrame:(CGRect)frame {
with no success. I would like to have this class work both with IB, and programmatically in the future. Everything works apart from the location of this initialization..
When objects load from a XIB file, they get -(id)initWithCoder:(NSCoder*)coder.
If you create objects from XIBs and programmatically, you'll need to implement both the designated initializer -initWithFrame:style: and -initWithCoder:, doing all your init stuff in each one.
Keeping those two in sync can be a pain, so most folks like to break the init stuff out into a private method, typically called -commonInit.
You can see an example of this in action in some of the Apple sample code: HeadsUpUI.
- (void)commonInit
{
self.userInteractionEnabled = YES;
}
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
[self commonInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder])
{
[self commonInit];
}
return self;
}
One common mistake that people make when they're new to Cocoa or Cocoa Touch, is to subclass when they don't actually need to. I've seen many examples of custom windows, tableviews, scrollviews and imageviews that need never have been written.
What functionality are you adding to UITableView? Are you sure that what you want to do can't be accomplished through the delegate methods, or by using a custom cell class?

Resources