One UIViewController with many UIViews - iphone

I'm creating an app with one UIViewController and many UIViews. I have MainViewController with a UIView underneath it that displays when loaded up and a few other UIViews all in the MainWindow.xib. How do I go about switching from one View to the next?
Update:
Thanks for the reply.
I have added MainViewController to my appDelegate.
On FinishedLaunching: [window addSubview:[viewController view]];
That View Controller has a function in it called goToNextPage.
-(IBAction)goToNextPage:(id)sender{
[self.view removeFromSuperview];
[self.view addSubview:tableOfContents];
}
In Interface Builder I have that View Controller added to MainWindow.xib. Under that View Controller I have a UIView (called Cover) that loads as it's child on startup and another UIView (eventually many) named TableOfContents that is on its own.
I tried to post an image of my MainWindow.xib here but apparently my Reputation isn't high enough.
The UIView Cover has a button on it that is linked to the goToNextPage function.
When I hit the button the page goes blank as if the one view is successfully being removed but the next is not being loaded.
How do I get the goToNextPage function to switch the preloaded UIView Cover with the other UIView called TableOfContents?
Another Edit:
BookTest6AppDelegate.h:
#import <UIKit/UIKit.h>
#class MainViewController;
#interface BookTest6AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
IBOutlet MainViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet MainViewController *viewController;
#end
BookTest6AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[window addSubview:[viewController view]];
[window makeKeyAndVisible];
return YES;
}
MainViewController.h
#import <UIKit/UIKit.h>
#class TableOfContents;
#interface MainViewController : UIViewController {
IBOutlet TableOfContents *tableOfContents;
}
#property (nonatomic, retain) IBOutlet TableOfContents *tableOfContents;
-(IBAction)fGoToTableOfContentsController:(id)sender;
-(IBAction)fGoToNextPageController:(id)sender;
#end
MainViewController.m
#import "MainViewController.h"
#import "TableOfContents.h"
#implementation MainViewController
#synthesize tableOfContents;
-(IBAction)fGoToTableOfContentsController:(id)sender{
[self.view removeFromSuperview];
[self.view addSubview:self.tableOfContents];
}
-(IBAction)fGoToNextPageController:(id)sender{
}
My UIView Classes basically just initiate buttons that link to the functions defined in MainViewController.h.

First you need to know when switching from one to another.
Then you say it to your MainController and addSubView to the mainController.view an another view.
Maybe if you give us more informations or code we could help you a little more :-)
Good Luck
Vincent
Edit :
[self.view removeFromSuperview];
Here you are removing the window view. I think it's not the better way ^^ Try
[ viewController.view removeFromSuperview ]; :-)
Does it work better ?
Edit :
Edit bis : han, it's my fault. You need to remove controller and add another one in the app delegate and not in your mainController (you could do it too, but no with your actual code).
You have two options :
1°) Declare all your controllers in your app delegate.
2°) Declare all your controllers in one main controller. But the main controller would be here to "control" others one.

Related

UIView Buttons loaded with XIB do not work

I've loaded a UIView (FirstView.m) with a separate XIB (SecondView.xib), but the buttons in that XIB crash the app. The code for the buttons (IBOutlet & IBAction) are in SecondView.m.
Do I need to point the code from SecondView.m to FirstView.m? I tried using #import and #class... but was unsuccessful.
The code I'm using is completely valid... I'm pretty sure the issue has something to do with the XIB being loaded into the UIView... and then possibly losing its connection to the implementation file. Thoughts?
Thanks in advance!
FirstView.h
#import <UIKit/UIKit.h>
#interface FirstView : UIViewController {
IBOutlet UIView *SecondViewPopUP;
IBOutlet UIButton *openBTN;
}
#property (nonatomic, retain) UIView *SecondViewPopUP;
#property (nonatomic, retain) IBOutlet UIButton *openBTN;
-(IBAction)showPopUp:(id)sender;
FirstView.m
#synthesize SecondViewPopUP;
#synthesize openBTN
- (void)viewDidLoad {
SecondViewPopUP.alpha = 0;
// Add IncidentsViewController to view
SecondView *SecondV=[[SecondView alloc] init];
SecondV.view.frame = CGRectMake(0, 0, 262, 269);
SecondV.view.clipsToBounds = YES;
[SecondViewPopUP addSubview:SecondV.view];
SecondViewPopUP.frame = CGRectMake(0, 76, 262, 269);
[SecondV release];
}
-(IBAction)showPopUp:(id)sender {
NSLog(#"Stats Button was pressed");
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
SecondViewPopUP.alpha = 1;
[UIView commitAnimations];
}
SecondView.h
#import <UIKit/UIKit.h>
#interface ShareViewController : UIViewController {
IBOutlet UIButton *share_facebook;
IBOutlet UIButton *share_twitter;
}
#property (nonatomic, retain) IBOutlet UIButton *share_facebook;
#property (nonatomic, retain) IBOutlet UIButton *share_twitter;
-(IBAction)shareOnFB:(id)sender;
-(IBAction)shareOnTwitter:(id)sender;
SecondView.m
#synthesize share_twitter, share_facebook;
- (void)viewDidLoad {
[super viewDidLoad];
}
-(IBAction)shareOnFB:(id)sender {
NSLog(#"Shared on FB");
}
-(IBAction)shareOnTwitter:(id)sender {
NSLog(#"Shared on Twitter");
}
First of all FirstView (and presumably SecondView) is a UIViewController not a UIView so naming it "FirstViewController" would be much clearer. Views and view controllers are very different things.
Secondly you are adding a UIViewController's view as a subview of another view on the line "[SecondViewPopUP addSubview:SecondV.view];" That's not how UIViewControllers are expected to be used and the UIViewController programming guide recommends against it for good reason.
Each custom view controller object you create is responsible for managing all of the views in a single view hierarchy. In iPhone applications, the views in a view hierarchy traditionally cover the entire screen, but in iPad applications they may cover only a portion of the screen. The one-to-one correspondence between a view controller and the views in its view hierarchy is the key design consideration. You should not use multiple custom view controllers to manage different portions of the same view hierarchy. Similarly, you should not use a single custom view controller object to manage multiple screens worth of content.
Finally if you were to post the error listed when your app crashes we would probably see that you are attempting to send -shareOnFB: or -shareOnTwitter: messages to an instance of "FirstView" which does not implement them because your nib bindings are not configured appropriately ie you set the File's Owner of the nib to be "SecondView" and then loaded it with an instance of "FirstView" as its owner. Impossible to say for sure without more data.

Subclassed? UITabBarController wont autorotate

Noobie so bear with me.
I've have been following the O'Rielyy Learning iPhone Programming and various threads on here to build my first iPhone App. So far so good, but the final stumbling block at the projects end is getting the App to autorotate (the beta using only uiwebviews was rejected for not auto-rotating)
I have the mail App delegate, which adds a UITabBarController
// myNewsUKDelegate.h
#interface myNewsUKDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
// myNewsUKDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Add the tab bar controller's view to the window and display.
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
There is are .h and .m files for tabBarController - I added all the UINavigationControllers in IB, which in turn add a UITableView
See image at http://flatearth.co.uk/nib.png (too noob to post images in questions!)
From my reading I understand that the issue is the UITabBarController I added to the main view needs to be 'subclassed' and have this code added.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
The next view down/in/subclassed (whatever the correct terminology is), which has .h and .m files is the FirstViewController which adds the table view, this has shouldAutorotateToInterfaceOrientation already set.
#interface FirstViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
UITableView *tableView;
NSArray *userList;
}
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#property (nonatomic, retain) NSArray *userList;
#end
#implementation FirstViewController
#synthesize tableView;
- (void)viewDidLoad {
[super viewDidLoad];
// I tried adding
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// lots of other code ; )
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
So the problem appears to be that when [self.window addSubview:tabBarController.view]; adds the tab bar it doesn't add the shouldAutorotateToInterfaceOrientation returning YES bit.
It appears that I need to add a tabBarController subclass, with the shouldAutorotateToInterfaceOrientation in it. So I read up and tried this, as suggested on the interwebs...
// tabBarController.h
#import <UIKit/UIKit.h>
#interface tabBarController : UITabBarController {
}
#end
// tabBarController.m
#import "tabBarController.h"
#implementation tabBarController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#end
and adding
#import "tabBarController.h"
to myNewsUKDelegate.m
But that fails with "error: accessing unknown 'view' class method" at the
[self.window addSubview:tabBarController.view];
line in myNewsUKDelegate.m
Further searching hasn't produced anything helpful and my recent Xcode knowledge has now ran dry : ( Any help appreciated.
From my reading I understand that the issue is the UITabBarController I added to the main view needs to be 'subclassed' and have this code added.
No, you don't need to do that. The tab bar controller determines if it supports a specific interface orientation or not by asking all its child controllers if they support this orientation. In your case, these seem to be navigation controllers, which in turn ask their current child controller if it supports the orientation.
In other words, you have to make sure that all your custom view controllers return YES for the desired interface orientation.
You don't need a subclass, you need a Category on UITabBarController. Basically you create a file called UITabBarController + Autoresize.h (and .m)
In the .h:
#import <UIKit/UIKit.h>
#interface UITabBarController (Autoresize)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;
#end
in the .m:
#import "UITabBarController + Autoresize.h"
#implementation UITabBarController (Autoresize)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//do custom checks here if you only want to autorotate it in certain views or whatever
}
#end
but as the other poster pointed out, ALL the parent views of the view you wish to rotate must support rotation.

Passing info from Facebook to UITabBarController

When my app first starts, it shows a main page to log in to Facebook. Then, it goes to the UITabBarController. The code that I have in my app delegate is the following:
//this is the .h
#interface NMeAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
MainViewController *controller;
UITabBarController *tabBar;
}
#property (nonatomic, retain) IBOutlet UITabBarController *tabBar;
#property (nonatomic, retain) MainViewController *controller;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
//this is the .m of the app delegate
#import "NMeAppDelegate.h"
#implementation NMeAppDelegate
#synthesize window;
#synthesize tabBar;
#synthesize controller;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
controller = [[MainViewController alloc] init];
[window addSubview:tabBar.view];
[window addSubview:controller.view];
[window makeKeyAndVisible];
return YES;
}
Inside of MainViewController, I actually have a UserInfo object, which has all of the information that I need for the UITabBarController. The problem is that after getting this info in the UITabViewController, how do I pass this UserInfo to the UITabBarController` or possible the ViewController that is inside the UITabBarController so they were able to access this UserInfo? How to do this?
I hope my question makes sense.
you need to have an instance of your UserInfo object available to the tab bar controller. probably pass it into a instance variable of type UserInfo in your UItabBarController/each view controller whenever you transition into the specified controller.
edit: you should really have this passed into the view Controller it needs to be in (since it doesn't appear you have a custom UITabBarController subclass), or you could use a shared UserInfo variable in your app delegate to keep up with the information.
But as the commenter said, the question is not very clear at all and i could be completely misunderstanding what you want to do.
Hope that helps.

Calling pushViewController on a UINavigationController does nothing (no crash)

I have a UINavigationController as one of the views inside a tab bar control. It looks fine, and I have a UIBarButtonItem that is supposed to load a subview. I have the button wired up to an IBAction that calls pushViewController but when I do this nothing happens. It doesn't crash or anything.. it just doesn't do anything. I've tried: using different view controllers as the subview (no luck). Does anybody have any suggestions? Here is my code:
Header file:
#import <UIKit/UIKit.h>
#import "FSSettings.h"
#import "MeasureSelector.h"
#import "Dashboard.h"
#interface DashboardNavigationController : UIViewController {
IBOutlet UINavigationController *navController;
IBOutlet UINavigationBar *navBar;
IBOutlet UIBarButtonItem *measureButton;
}
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#property (nonatomic, retain) IBOutlet UINavigationBar *navBar;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *measureButton;
- (IBAction) showMeasureScreen:(id)sender;
#end
And the .m file containing the action:
// Displays the measure screen
- (IBAction) showMeasureScreen:(id)sender
{
NSLog(#"Loaded measure screen");
MeasureSelector *msel = [[MeasureSelector alloc] initWithNibName:#"MeasureSelector" bundle:nil];
[[self navigationController] pushViewController:msel animated:YES];
NSLog(#"Done.");
}
When I click the button nothing happens (but I do see the log messages). I can do this over and over with no ill effects, however.
The navigationController property of UIViewController refers to the nav controller of which the UIViewController is part of the hierarchy. If I understand the scenario correctly, DashboardNavigationController manages the view that is the container for the UINavigationController, so it makes sense that this property would be nil.
Use the outlet you created to access the nav controller from outside of the nav controller's hierarchy.

Should I put my UITabBarController outside the App Delegate?

I followed an example from "Beginning iPhone 3 Development" which puts the code for the main view controller, a Tab Bar, in the delegate method. Is this the correct place to put this or should it be in a separate .h and .m file? All my subviews are in separate files so I'm wondering if I should have my tab bar view controller code in a separate file also.
Also, for the subviews I call ViewDidLoad as normal but there is no ViewDidLoad in the delegate method, I guess because it's of type NSObject and not UIViewController. Should I change the delegate to a type UIViewController so I can call ViewDidLoad?
Thanks, code samples of my existing app are below.
Header file for Delegate:
#import <UIKit/UIKit.h>
#interface MyAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *rootController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *rootController;
#end
Beginning of Delegate implementation file
#import "MyAppDelegate.h"
#implementation MyAppDelegate
#synthesize window;
#synthesize rootController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Add the tab bar controller's current view as a subview of the window
[window addSubview:rootController.view];
[window makeKeyAndVisible];
}
Is this the correct place to put this or should it be in a separate .h and .m file?
Should I change the delegate to a type UIViewController so I can call ViewDidLoad?
no this is your initial load point, not a view controller. Even if you change its type, the view did load method will not be called, the app delegate is not a view controller. It is here you load your initial view controller. UITabbar (according to the doco) "This class is not intended for subclassing." see here. (so no .h and .m file, what would you derive from?) you should not need to subclass, as you will get your viewdidload method for each of the views you put in your tab bar.