Confusion about initWithNibName and loadView - objective-c

Is the initWithNibName always called whenever programmatically or IB?
Example:
I have two viewController, one named PhotoViewController, the other named ViewController.
The PhotoViewController creates view programmatically, but with initWithNibName uncommented.
Here is my PhotoViewController.m:
- (void)loadView
{
NSLog(#"loadView in PhotoView");
UIView *view = [[UIView alloc] initWithFrame:[UIScreen
mainScreen].applicationFrame];
[view setBackgroundColor:[UIColor redColor]];
self.view = view;
[view release];
}
// Loading views from a nib file.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
NSLog(#"PhotoViewController initWithNibName=%#",nibNameOrNil);
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
Here is my call in ViewController.m
- (void) doSearchFlickr
{
PhotoViewController *pController = [[PhotoViewController alloc]init];
[self.view addSubview:pController.view];
[pController release];
}
Then I see something confusing me in the log:
2011-10-23 10:52:52.151 TableViewPG[1192:b303] PhotoViewController initWithNibName=(null)
2011-10-23 10:52:52.153 TableViewPG[1192:b303] loadView in PhotoView
According to the ViewControllerPGforiPhoneOS on page 30, if I override loadView programmatically, initWithNibName should not be called.
Is there any flaw(s) in my logic?

-[UIViewController init] just executes [self initWithNibName:nil bundle:nil]. You can easily check this by putting a breakpoint in your -[PhotoViewController initWithNibName:bundle:] and looking at the call stack.
Your -[PhotoViewController loadView] is fine.
The View Controller Programming Guide for iOS doesn't say anything about initWithNibName:bundle: on page 30.

Related

How can I pas another object's function as a selector in IOS?

I've read selector as parameter in IOS post. However, I want to extend the question.
In my case, I'm creating an Objective-C (not Swift) Master/Detail application, and want to create DetailController object of type UIViewController with the following init function
In DetailViewController.h
#interfact DetailViewController : UIViewController
- (id)initWithNibName:(NSString *)nibName withSaveSelector:(SEL)saveSelector
#end
... and in DetailViewController.m
- (id)initWithNibName:(NSString *)nibName withSaveSelector:(SEL)saveSelector
{
self = [super initWithNibName:nibName bundle:nil];
if (self) {
UIBarButtonItem *done = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:saveSelector];
[[self navigationItem] setRightBarButtonItem:done animated:YES];
}
return self;
}
NOW, I want to just keep re-using above code to create different DetailViewControllers, and want to pass a saveSelector function that will get called when the user presses the "Done" button.
Now I have another view controller
#interface AnotherViewController : UIViewController
- (void)saveSelector:(id)sender;
#end
...and then in yet another object (i.e., NOT in AnotherViewController.m code), I use the above view controller, like so...
AnotherViewController *avc = [[AnotherViewController alloc] init];
DetailViewController *dvc = [[DetailViewController alloc] initWithNibName:#"AnotherViewController" withSaveSelector:#selector(???)];
What should I put in the ??? so I can pass AnotherViewController::saveSelector() function to DetailViewController?
I hope that makes sense.
Change your method as:
- (id)initWithNibName:(NSString *)nibName withSaveSelector:(SEL)saveSelector forTarget:(id)target
And call it like this:
DetailViewController *dvc = [[DetailViewController alloc] initWithNibName:#"AnotherViewController" withSaveSelector:#selector(saveSelector:) forTarget:avc];
In DetailViewController.m
- (id)initWithNibName:(NSString *)nibName withSaveSelector:(SEL)saveSelector forTarget:(id)target
{
self = [super initWithNibName:nibName bundle:nil];
if (self) {
UIBarButtonItem *done = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:target
action:saveSelector];
[[self navigationItem] setRightBarButtonItem:done animated:YES];
}
return self;
}

Upside down Orientation issue in iOS6

I am creating a sample empty application and added UIViewController class,
Below is the code in the App delgate
TestViewController* viewController = [[TestViewController alloc] initWithNibName:#"TestViewController" bundle:nil];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[self.window setRootViewController:navController];
Now i am rotating the App but in the UPsidedown Orientation Navigation bar is not Rotating I am attaching a screen shot
Then Added a the Below Method in App delegate
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAll;
}
And in the Class i have added following methods
-(BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskAll);
}
In the Summary i have activated all the orientations can any One tell me the Solution for it
1) just You created a category for UINavigationController class and I defined these methods
In CustomViewController.h
#import <UIKit/UIKit.h>
#interface CustomViewController : UINavigationController
#end
In CustomViewController.m
#import "CustomViewController.h"
#interface CustomViewController ()
#end
#implementation CustomViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL) shouldAutorotate{
return YES;
}
-(NSUInteger) supportedInterfaceOrientations{
return UIInterfaceOrientationMaskAll;
}
And AppDelgate.m file
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
CustomViewController *navController = [[CustomViewController alloc] initWithRootViewController:self.viewController];
// Override point for customization after application launch.
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
2) And check Orientation In Target
3) Change the class from UINavigationController to the CustomViewController in my XIB in IB
4) Reset the Simulator and run the code, I think your problem will be solve.
i think you need to use
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return TRUE;
}
instead of shouldAutorotate
Upside Down button to ON in Supported interface orientations on Xcode
http://www.appcoda.com/ios-game-tutorial-maze-part-1/
`TestViewController* viewController = [[TestViewController alloc] initWithNibName:#"TestViewController" bundle:nil];
[self.window setRootViewController:viewController];`
remove the navigatioan bar from appdelegate and then check

How to put a tab bar only in certain place in the app?

I want to put a tab bar for one place in my app. From there i can load some other view controllers, but that's it. I don't want it for my whole application. All examples I read through are making the tab bar controller as the rootviewcontroller of the window.
So how do i do that?
Thank you!
his may help you, Consider your view controller is HomeView where from you are going to push a tab bar controller, The HomeView is loaded in view at below:
#import "AppDelegate.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
HomeView *homeview = [[HomeView alloc] initWithNibName:#"HomeView" bundle:nil];
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:homeview];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}
#end
then the .h, .m and .xib files of HomeView are going to be as follows:
In HomeView.h
#import <UIKit/UIKit.h>
#interface HomeView : UIViewController
{
IBOutlet UITabBarController *tabBarController;
}
-(IBAction)loadTabBar:(id)sender;
#end
and the HomeView.m is:
#implementation HomeView
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(IBAction)loadTabBar:(id)sender
{
[self.navigationController pushViewController:tabBarController animated:YES];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
and the .xib file must be as follows:
The tabBarController IBOutlet must be connected to the UITabBarController that on the .xib file. And that UITabBarController with two view controllers named FirstViewController, SecondViewController. Moreover that the HomeView must be inside a UINavigationController.
If not clarified with this answer, I'll update with detailed explanation.
The above is a way of loading tab bar controller using XIB method.
You can do this by coding like below by changing something in IBAction(button action) , In HomeView.m file:
#import "HomeView.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#implementation HomeView
-(IBAction)loadTabBar:(id)sender
{
FirstViewController *firstView = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *secondView = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:firstView, secondView, nil];
[self.navigationController pushViewController:tabBarController animated:YES];
}
#end
You have to make tabBar in app delegate and then add when ever you want using this
-(void)addTabBarController
{
AppDelegate *appdelegte =(AppDelegate*)[[UIApplication sharedApplication]delegate];
//[[[appdelegte navigationController] view]removeFromSuperview];
[[appdelegte window]addSubview:[[appdelegte tabcontroller]view]];
[[appdelegte tabcontroller]setSelectedIndex:0];
}

UITableViewController bottom toolbar does't work?

I have UINavigationController and UITableViewController as root.
myViewController = [[MyViewController alloc] init];
UINavigationController * navContr = [[UINavigationController alloc] initWithRootViewController:myViewController];
[self.window addSubview:[navContr view]];
I need bottom toolbar with buttons for MyViewController view. Found in google that I should set:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
[self.navigationController setToolbarHidden:NO];
}
return self;
}
But there is no bottom toolbar in my TableView. What should I do???
Google said that?
Try starting over and make a Tab Bar Controller. http://www.panolee.com/antonimasso/tutorials/tab-bar-application
Then add a TableViewController to it.

Using UINavigationController with UIViewControllers instances of the same class, and no NIB

While trying out an experimental UINavigationController-based iPhone application, I ran into a problem when the user navigates back to the previous view.
The simple application uses a UINavigationController, onto which new instances of UIViewControllers are pushed.
These instances are all of the same class (in this example, class MyViewController a sub-class of UIViewController), and are manually created (not using a NIB). Each instance contains a separate UITableView instance as the UIViewController's view.
The following tableView:didSelectRowAtIndexPath: method is from the MyViewController class. It creates and pushes another MyViewController instance onto the navigationController when the user selects a table cell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyViewController *nextViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:nextViewController animated:YES];
[nextViewController release];
}
The user can navigate forwards through a sequence of views, each one containing a table. The problem occurs when navigating back to the previous screen. The application aborts and xcode starts the debugger.
The error can be prevented by not releasing the MyViewController instance in the tableView:didSelectRowAtIndexPath: method above, or by not calling dealloc on the 'myTableView' instance in MyViewController's dealloc method.
However, that's not a real solution. As far as I know, the UINavigationController "owns" the pushed UIViewController instance, which can then safely be released from the client that allocated it. So, what can be wrong with this experimental app? Why would it terminate when the user navigates back?
Below are a few other methods of the MyViewController class:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
self.title = #"My Table";
myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
myTableView.delegate = self;
myTableView.dataSource = self;
self.view = myTableView;
}
return self;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyTable"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0,0, 300, 50) reuseIdentifier:#"MyTable"];
[cell autorelease];
}
cell.text = [NSString stringWithFormat:#"Sample: %d", indexPath.row];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3; // always show three sample cells in table
}
- (void)dealloc {
[myTableView dealloc];
[super dealloc];
}
EDIT:
Problem fixed - thanks Rob Napier for pointing out the problem.
The -loadView method now sets up the view using a local UITableView instance:
- (void)loadView {
UITableView *myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
myTableView.delegate = self;
myTableView.dataSource = self;
self.view = myTableView;
[myTableView release];
}
You're setting the view in the wrong method. You should set this up in -loadView, not -initwithNibName:bundle:. Look in View Controller Programming Guide "Using View Controllers" for an example.