A buddy of mine asked for a quick sample of code for an app skeleton that would use a TableView to call a TabView. I estimated an hour.
After more hours than I want to admit messing around in IB, I gave up and implemented the following code.
Can anyone tell me how to do this in IB? I was careful (I thought) to make all the right connections, but no go. I even had another (working) app where I went through and step-by-step made the same connections. I got errors about "Changing the delegate of a tab bar managed by a tab bar controller is not allowed..." (This when I connected the TabBar's delegate to the File's owner, even though another app was working fine with that setting)
Until I wrote this code, I never got the tabbar view, only the view that came with the view xib... (I tested by putting a label on the view).
Thanks in advance...
UITabBarController *tabBarController = [[[UITabBarController alloc] initWithNibName:nil bundle:nil] autorelease];
NumberOneViewController *numberOneViewController = [[[NumberOneViewController alloc] initWithNibName:#"NumberOneViewController" bundle:nil] autorelease];
NumberTwoViewController *numberTwoViewController = [[[NumberTwoViewController alloc] initWithNibName:#"NumberTwoViewController" bundle:nil] autorelease];
NumberThreeViewController *numberThreeViewController = [[[NumberThreeViewController alloc] initWithNibName:#"NumberThreeViewController" bundle:nil] autorelease];
NumberFourViewController *numberFourViewController = [[[NumberFourViewController alloc] initWithNibName:#"NumberFourViewController" bundle:nil] autorelease];
tabBarController.viewControllers = [NSArray arrayWithObjects:numberOneViewController, numberTwoViewController,
numberThreeViewController, numberFourViewController, nil];
[self.navigationController pushViewController:tabBarController animated:YES];
self.view = tabBarController.view; in the viewDidLoad method of the TabBarController delegate class fixed it...
Ah well, surely someone else will run into the same thing and hopefully this will help them...
Related
I have several .xib files (page1, page2 ...) and want to switch between them using buttons (as a navigation bar)
I am using
page1 *second = [[page1 alloc] initWithNibName:nil bundle:nil];
second.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:second animated: YES];
page2 *second = [[page2 alloc] initWithNibName:nil bundle:nil];
second.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:second animated: YES];
and so on...
I learned that this consumes a lot of memory because I am presenting a view over and over again and after switching back and forth the app sometimes crashes.
So, question is what can I do?
I tried this:
[self dismissModalViewControllerAnimated:YES]
but after dismiss it returns to the previous page and I can not navigate to another one.
Probably I used a stupid approach, however, I've done a few apps that way and don't want to change the controller completely.
Thank you for your help!
I think you have to create IBActions from that 2 blocks of code an link that IBActions to the right button.
Apologies if this is a basic question but I am new to Xcode and have a storyboard app and in the storyboard (with no segue) I have a view controller with an embedded map view.
On the storyboard screen I have an image with a tap gesture linked, I have tested the tap and it works (NSLog) but I want to know how to launch my mapview view controller and also zoom to an x&y.
My code currently has
-(IBAction)handleMapTap:(UIGestureRecognizer *)sender {
NSLog(#"Tapped");
}
& I have tried;
MMMapViewController *mapViewController = [[MMMapViewController alloc] initWithNibName:#"MapView" bundle:nil];
[self.navigationController pushViewController:mapViewController animated:YES];
My view controller has a class set as MMMapViewController I have given the view controller a storyboard id of MapView (if it's required?).
I've read a lot of stackoverflow articles but can't seem to find an answer. If anyone can help I would be really grateful.
-(IBAction)handleMapTap:(UIGestureRecognizer *)sender
{
MMMapViewController *mapViewController = [[MMMapViewController alloc] initWithNibName:#"MapView" bundle:nil];
//[self.navigationController pushViewController:mapViewController animated:YES];
[self presentModalViewController:mapViewController animated:YES];
[mapViewController release];
}
It would probably help to know what self is, if it is indeed a UIViewController, then
I would make sure that self.navigationController is not nil.
You actually have the right code, as far as I can tell, but depending on your scenario, you could get away with presenting the mapView as a modal view controller.
Ok, it's 3 am atm and I haven't a clue where I put this:
[navigationController.navigationBar setTintColor:[UIColor redColor];
If you would please post the whole .m/.h files that would be great. Also, do I connect anything using segues or outlets? And when you create the .h/.m files do I need UINavigationController or similar selected or just the normal UIViewController? Thanks.
Update: Nevermind I got it, thanks though. Below is the code for others having my issue.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UINavigationBar *bar = [self.navigationController navigationBar];
[bar setTintColor:[UIColor lightGrayColor]];
}
Basically just add on to what's already there.
I feel stupid lol.
You can set that value right after you init your UINavigationController, i.e:
UINavigationController *controller = [[UINabvigationController alloc] initWithRoot...
[controller.navigationBar setTintColor:[UIColor redColor]];
the master detail application included when you use Storyboards this code in view did load.
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
i want to use this like in same project with .xib'S
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(showGegenstellenView)];
the problem is that i can't implement this code in the storyboard project. I can't find help special for storyboards...
-(void)showGegenstellenView{
GegenstellenViewController *gegenstellenViewController = [[GegenstellenViewController alloc]initWithMasterController:self Gegenstellen:nil];
[self presentModalViewController:gegenstellenViewController animated:YES];
}
Finally I want to click in the table view the add button and a view comes with a formular.
All this works in the project with xib's i have. But i want it with storyboards! I have no problem when u want see the xib project via team viewer or as sib by mail.
Best Regards
John
Hi I have a splitview app that is working fine until I add a TabBar in the rootview section. The problem is that when I add the TabBar to the rootview the app does not rotate to landscape, if I change the orientation the view remains in portrait mode.
How can I solve this?. Hope you can help
#import "SplitViewTest3AppDelegate.h"
#import "SISACWelcomeViewController.h"
#implementation SplitViewTest3AppDelegate
#synthesize window, masterViewController, splitViewController,masterViewTabBarController, searchViewController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
masterViewController = [[MasterViewController alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
masterNavigationController.tabBarItem.image = [UIImage imageNamed:#"Folder.png"];
//NewsFeedsNavigationController *newsFeedsNavigationController = [[NewsFeedsNavigationController alloc] init];
SISACWelcomeViewController *sisacWelcomeViewController = [[SISACWelcomeViewController alloc] init];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:sisacWelcomeViewController];
searchViewController = [[UIViewController alloc] initWithNibName:#"SearchView" bundle:nil];
searchViewController.tabBarItem.image = [UIImage imageNamed:#"Search-icon.png"];
masterViewTabBarController = [[UITabBarController alloc] init];
masterViewTabBarController.viewControllers = [NSArray arrayWithObjects:masterNavigationController, searchViewController, nil];
masterViewController.detailNavigationController = detailNavigationController;
splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = [NSArray arrayWithObjects:masterViewTabBarController, detailNavigationController, nil];
splitViewController.delegate = sisacWelcomeViewController;
// Add the split view controller's view to the window and display.
[window addSubview:splitViewController.view];
//[masterNavigationController.view addSubview:tab.view];
[window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
/*
Restart any tasks that were paused (or not yet started) while the application was inactive.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application {
/*
Called when the application is about to terminate.
*/
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
/*
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
*/
}
- (void)dealloc {
[window release];
//[tab release];
[super dealloc];
}
#end
The answer below is correct. If you are adding tabs which include using the CoreDataTableView controller (that is used with the CS193P course), be sure to add a method to allow for any orientation. If not, your split view will not work correctly.
SOLVED:
I had the same issue.
Without the TabBar all is well, add the TabBar and the rotation breaks.
I guessed that there is something broken in the responder chain or view hierarchy.
So I was about to submit as a bug. So wrote a test app to demo to Apple (because they ALWAYS ask for one), and it worked. Hooray, but why?
These are my findings from the Apple docs.
From the View Programming Guide for iOS.
Split View Controller
"A split view controller must always be the root of any interface you create."
Thus they should not be embedded within a TabBar View, although I understand that there is a workaround out in the wild.
Also:
Creating a Tab Bar Interface
"Install it as one of the two root views in a split view interface. (iPad only)"
Solution:
After much more investigation, and some trial and error, I found the issue.
Of course it seems so obvious NOW.
When the SplitView tests for shouldAutorotateToInterfaceOrientation, it tests every possible view on the whole hierarchy, that is EVERY view in the MasterView, thus EVERY view in the TabBar, and EVERY view in the DetailView, thus EVERY view in the current NavigationStack.
The fly in the ointment is that a newly created ViewController does not support Landscape by default.
Where I had gone wrong was: I had created ALL of the TabBar subviews, but not written any more code yet, because I wanted to get the SplitView with TabBar working first, thus 1 of my Tab Views had not been changed from the default.