Objective-C Modal View - iphone

Is it possible to present a modal view from a UIView or a UIWindow in the same .xib?
here is my code:
#interface MyViewController : UIViewController <UIWebViewDelegate> {
IBOutlet UIVIew *myView
}
#property (nonatomic, retain) UIView *myView;
- (void)somefunction;
And my function:
- (void)somefunction {
//here i need to make my view1 gets presented by a modal view style.
}

You need to add IBOutlets for your views. In your MyViewController.h file:
...
IBOutlet UIView *firstView;
IBOutlet UIView *secondView;
...
Then you connect the outlets using Interface Builder (or Xcode 4). After that, in your implementation file you manually hide or show the view that you want.
PresenterViewController.m:
- (void)ShowSecondView{
//Initialize the view controller
MyViewController *modalView = [[MyViewController alloc] initWithNibNamed:#"MyViewController" bundle:nil];
//Hide or show whatever view(s) you want
[modalView.firstView setHidden:YES];
[modalView.secondView setHidden:NO];
//Present the view controller modally
[self presentModalViewController:modalView animated:YES];
//Don't forget memory management!
[modalView release];
}
You may need to tweak this code a little bit, but this is the general idea.

Related

ViewController Not Rotating

I have been having issues forever with an app, and getting certain views to rotate.
I already know that no view in a tab bar controller can rotate, unless ALL are allowed to rotate. I also know that no view within a navigation controller can rotate unless the top most view is allowed to rotate.
I used IB mostly to setup my app.
In the MainWindow.xib I have the AppDelegate Object, Window, TabBarController, and then a separate UIViewController.
Within one of the tabs of the tab bar, I have an IBAction linked to a UIButton with the following code:
-(IBAction)stuff {
[self presentViewController:buletinss animated:YES completion:nil];
}
The view controller is declared in the header file as an IBOutlet, and is linked from that tab class to the UIViewController. In IB, I then set the class for that view controller to a UIViewController class I set up, and return YES to allow it to rotate.
However, it still will not rotate.
I thought that since it was not a part of the tab bar, and not pushed from a navigation controller, that it would be allowed to rotate, but I am having no luck. Please any help?
Here is full code:
First, the .h and .m for the view that has the button:
#import <UIKit/UIKit.h>
#interface BulletinViewController : UIViewController {
IBOutlet UIWebView *worship;
IBOutlet UIActivityIndicatorView *activity;
NSTimer *timer;
IBOutlet UIViewController *buletinss;
}
-(IBAction)stuff;
#property (nonatomic, retain) UIActivityIndicatorView *activity;
#end
and the .m
#import "BulletinViewController.h"
#implementation BulletinViewController
-(IBAction)stuff {
[self presentViewController:buletinss animated:YES completion:nil];
}
Now the .h and the .m of the view it is presenting
#import <UIKit/UIKit.h>
#interface TestBulletinViewController : UIViewController
#end
and the .m
#import "TestBulletinViewController.h"
#implementation TestBulletinViewController
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Try change this code
[self presentViewController:buletinss animated:YES completion:nil];
to
[self presentModalViewController:buletinss animated:YES];
UPD: in iOS 6 you must:
1)
Replace
[window addSubview:buletinss.view];
with
window.rootViewController = buletinss;
2)
Add this code lines
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
It's hard to know what's going on without seeing your project. You're doing a very odd thing: why are you loading a view controller from a nib? You are saying:
IBOutlet UIViewController *buletinss;
Why? Why are you not explicitly instantiating a BulletinViewController and setting the ivar to that?
I'm betting that the problem is that in the nib, this object is not a BulletinViewController. It's probably just a generic UIViewController. Hence your BulletinViewController code is irrelevant; none of it ever runs. Instead, you've got a generic UIViewController that only rotates to portrait. But that's just a guess.

iOS5 Custom Tab Bar

I am new to Iphone and I have started an application in which I have added a custom tab bar which has to load to some particular page only. The tab bar works as per my expectation. Now the problem is that, when I navigate to other pages the tab bar keeps on showing and it cause serious problem for me...
Here is my implementation
In .h:
#import <UIKit/UIKit.h>
#class MainMenuViewController;
#interface RoutineListViewController : UIViewController<UITabBarDelegate>{
MainMenuViewController *homeBtn;
UITabBar *mainTabBar;
UIViewController *routineTabViewController;
UIViewController *calendarTaViewController;
UIViewController *editTabViewController;
}
#property (nonatomic, retain) IBOutlet UITabBar *mainTabBar;
#property (nonatomic, retain) IBOutlet UIViewController *routineTabViewController;
#property (nonatomic, retain) IBOutlet UIViewController *calendarTabViewController;
#property (nonatomic, retain) IBOutlet UIViewController *editTabViewController;
- (IBAction)goToHome:(id)sender;
#end
In .m, i am implementing the tab as:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
switch (item.tag) {
case 1:
if (routineTabViewController == nil) {
self.routineTabViewController =[[RoutineListViewController alloc] initWithNibName:#"RoutineListViewController" bundle:nil];
[self.view insertSubview:routineTabViewController.view belowSubview:mainTabBar];
routineTabViewController = nil;
[routineTabViewController release];
}
break;
case 2:
if (calendarTabViewController == nil) {
self.calendarTabViewController =[[CalendarTabViewController alloc] initWithNibName:#"CalendarTabViewController" bundle:nil];
[self.view insertSubview:calendarTabViewController.view belowSubview:mainTabBar];
calendarTabViewController = nil;
[calendarTabViewController release];
}
break;
case 3:
if (editTabViewController == nil) {
self.editTabViewController =[[EditTabViewController alloc] initWithNibName:#"EditTabViewController" bundle:nil];
[self.view insertSubview:editTabViewController.view belowSubview:mainTabBar];
editTabViewController = nil;
[editTabViewController release];
}
break;
default:
break;
}
}
And when I implement a button to go to some other page, the tab bar keeps showing. Here is the button implementation in EditTabViewController.m file.
- (IBAction)goToHome:(id)sender {
homeBtn = [[MainMenuViewController alloc] initWithNibName:#"MainMenuViewController" bundle:nil];
[self.view addSubview:homeBtn.view];
}
Per Apple's rules, a TabBarController is supposed to be the main container. Plus, if you just implement a custom UITabBar, are you using that to push the user into other views? If so, if the UITabBar disappears, how does the user ever return?
If you only want the bar visible when a particular page is visible, why not implement a UINavigationController (as the main container) and have the root UIViewController implement a UIToolbar that performs the same functions. Then, when you navigate to another page (I'm assuming here that you mean a new screen, not a different page in a UIPageControl or a web page in a UIWebView), you push in a new UIViewController that doesn't contain the UIToolbar.
Kind of like this:
--UINavigationController
|
-->UIViewController as RootViewController --> Contains UIToolbar
|
-->Pushes UIViewController --> Has no UIToolbar
Edit/Update
I just saw your code, and I'm not sure I understand what you're trying to achieve. I think you might be trying to somehow implement behavior similar to a UINavigationController without actually using one.
Edit/Update #2
I think you are wanting behavior that can be implemented like this:
UINavigationController (containing IconMenuViewController as RootViewController)
|
--> PageViewController (push into this from any icon touch in IconMenuViewController)
--> Contains UIToolbar/UITabBar
If you use the hierarchy above, the UINavigationController will automatically provide you with the NavigationBar at the top of the screen and give you a back button. As long as you make the UIToolbar or UITabBar part of the PageViewController, it should appear and disappear with its view controller as you push and pop it. Does that make sense?

Advice with Tab Bar and Nav Bar

I'd just like to clear something up..
I have an app where the Main Window UI has a Tab bar with 3 tabs (opt1, opt2, op3). Each opt has its own xib file where i've drawn their own interfaces.
In my app delegate class I have included a UITabBar *rootController, and hooked this up to my tab bar in my Main Window xib file.
Now.. In the Tab bar, I have dragged in 3 navigation controllers (1 for each opt) and inside each one I have a 1) tab bar icon, 2) navigation bar and 3) view controller.
Back in my app delegate.h class I have included code for UINavigationController *nav1, nav2, nav3..and hooked these up accordingly in IB in MainWindow.xib (TabBar->navController1, navController2, navController3).
Is this the right way to do it? Also how can I make use of these nab bars in my opt1, opt2, opt3 class files?
here is my code:
app delegate.h
#import <UIKit/UIKit.h>
#class LoginViewController;
#interface myAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
UINavigationController *navigationController1, *navigationController2, *navigationController3;
IBOutlet UITabBarController *rootController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController1, *navigationController2, *navigationController3;
#property (nonatomic, retain) IBOutlet UITabBarController *rootController;
#end
appdelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:[rootController view]];
[window makeKeyAndVisible];
LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:nil];
[self.rootController presentModalViewController:loginViewController animated:NO];
}
Then in my LoginController.m class , when the user enters correct credentials I call
[self dismissModalViewControllerAnimated:YES];
In my MainWindow.xib, I hook up my rootController to a TabBarController. In the TabBarController I have put 3 NavigationControllers inside it and linked them to 3 tabOption classes which each have their own .xib view.
The tab bar switches between the 3 option views nicely. However in 1 .xib view I have a button to open a new .xib. So in my tabOption1 class I have the following:
-(IBAction)openBook:(id)sender{
UIViewController *nextVC = [[PageViewController alloc] initWithNibName:#"PageView" bundle:nil];
[self.navigationController pushViewController:nextVC animated:YES];
}
However this does not open up my PageView.xib... I have connected it to my PageViewController class and everything too..and the button works because I've tested it with a UIDialog
Have you seen the Apple Programming Guides? They might give you a better understanding of how everything ties together - you could start here:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/NavigationControllers/NavigationControllers.html#//apple_ref/doc/uid/TP40007457-CH103-SW1
In answer to your question, that looks like an OK way of setting up. I really would recommend reading up a bit though :)
In response to your comment, that looks like a reasonable way to do what you're trying to achieve. If it works, then it works.
In response to your other issue then you can get the navigation controller object by doing this: self.navigationController
So you can "go to" a new view controller like this:
// make the view controller
UIViewController *nextVC = [[MyCustomViewController alloc] initWithNibName:#"MyCustomViewController" bundle:nil];
// push it onto the navigation stack
[self.navigationController pushViewController:nextVC animated:YES];
To add this to the click event on a button you need to create the button in interface builder and create an IBAction in your code. The IBAction might look like this:
- (IBAction)pushNextViewController:(id)sender {
UIViewController *nextVC = [[MyCustomViewController alloc] initWithNibName:#"MyCustomViewController" bundle:nil];
[self.navigationController pushViewController:nextVC animated:YES];
}
Then you need to link to it from interface builder. I'm not sure how to do this, I generally don't use interface builder, and certainly haven't used it since about XCode 3.
To do it programatically you can use this method:
[MyButton addTarget:self selector:#selector(pushNextViewController:) forControlEvents:UIControlEventTouchUpInside]; // always use touch up inside
Keywords to look up to help you find tutorials and stuff on the internet: ibaction uinavigationcontroller pushviewcontroller:animated: popviewcontrolleranimated:

Switching Content Views Issue

I'm attempting to switch views with an iPhone application- I have a parent view controller, SuperviewController, and then two views that I want to switch within that parent view, MainMenuController and MainGameController.
*EDIT*: I am now using navigation controllers:
SuperviewController.m
viewDidLoad
self.mainMenuController = [[MainMenuController alloc] initWithNibName:#"MainMenu" bundle:nil];
[[self navigationController] pushViewController:self.mainMenuController animated:NO];
switchToMainGame
self.mainGameController = [[MainGameController alloc] initWithNibName:#"MainGame" bundle:nil];
[[self navigationController] pushViewController:self.mainGameController animated:NO];
The app loads correctly with the mainMenu.xib. However, when calling switchToMainGame, nothing happens- it's as if XCode forgot what mainGameController is.
Thanks for any help.
You might consider swapping view controllers not views, using UINavigationController.
In your AppDelegate.h
#interface AppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
UINavigationController *navigationController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#end
And in -[AppDelegate applicationDidFinishLaunching:] instantiate navigationController, thus:
[self setNavigationController:[[UINavigationController alloc] initWithRootViewController:mySuperviewController]];
[[self navigationController] setNavigationBarHidden:YES];
// Configure and show the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
Then within SuperviewController.m you can instantiate your MainMenuController and MainGameController, as you already do. To start with MainMenuController you could do this in SuperviewController -viewDidLoad
[[self navigationController] pushViewController:[self mainMenuController] animated:YES];
You would need to add some smarts to switch directly between mainMenuController and mainGameController - but it wouldn't be difficult.
So as not to reload nibs again and again, consider defining accessor methods like this:
- (MainGameController*) mainGameController
{
if (mainGameController == nil)
{
mainGameController = [[MainGameController alloc] initWithNibName:#"MainGame" bundle:nil];
}
return mainGameController;
}
Also, bear in mind that switching between sibling view controllers involve popping current view controller (e.g., mainMenuController) before pushing other view controller (e.g., mainGameController).

TabBar application, moreNavigationBar and nibs with navigationBars

I have a TabBar application with several nibs, most with a NavBar. It works pretty well, except for the "views" that are inside the "More" section of the tabBar.
As expected, it will put a NavBar to return to the "More" list, as well as the NavBar i've placed in the nib.
I've tried to remove the view controllers from the moreNavigationBar and put the top controller from my nib's navBar, but I get and extra view from somewhere:
- (void)viewDidLoad {
TestAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
UITabBarController *ctrl = appDelegate.rootController;
UINavigationController *navCtrl = ctrl.moreNavigationController;
[navCtrl popToRootViewControllerAnimated: NO];
[navCtrl pushViewController: navController.topViewController animated: YES];
navController = navCtrl;
[super viewDidLoad];
}
My AppDelegate:
#interface TestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UITabBarController *rootController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *rootController;
The MainWindow nib is that of a Window-based project with a TabBarController, linked to the rootController in my app delegate.
The other nibs have a view + navigationController and I have a UITableViewController subclass as my Root View Controller.
If I could get this to work it wouldn't still solve my problem, because I want to allow the user to place this anywhere in the tabBar, so, I must have some way of knowing if there's a navigationBar.
So, my question is, how do you know if there's a navigationBar (in this case, if the tabBar's navigationBar is being shown) and, if so, how do I get my navigationController to "become" the tabBar's navigationController?
Or, if you have another idea on how to solve this problem, i'd also be appreciated :)
The recommendation from apple is that you have the TabBar controller contain the Navigation controllers and not the other way around. I have a setup more or less like this, and I have the More tab hold a Nav controller, basically like this:
#interface SomethingNavViewController : UIViewController {
UIView* aview;
UINavigationController *navigationController;
}
#property (nonatomic, retain) IBOutlet UIView *aview;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#end
In the NIB, I have a separate Nav controller in the view of the more panel, I haven't replaced the tab bar item's view with a nav controller view, I've just added a Nav controller to the view.
In my implementation file, I have:
- (void)viewDidLoad {
[super viewDidLoad];
[[self view] addSubview:[navigationController view]];
SomeOtherController *aController = [[[SomeOtherController alloc ] initWithNibName:#"SomeOtherController" bundle:nil ] autorelease];
aController.title = #"Artwalks";
// lots of application logic here.
[self.navigationController pushViewController:aController animated:YES];
[self.navigationController setDelegate:self];
}
One key thing about this is that I have implemented the navigationController's delegate method, which is really handy when you're just inserting the nav controller. I found when I didn't do this, my views don't get viewDidAppear messages, so I implemented the protocol and added this method:
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([viewController respondsToSelector:#selector(viewDidAppear:)]) {
[viewController viewDidAppear:animated];
}
}
and that solved a variety of my lingering problems.
Anyway, I hope this answer gave you the detail you needed. IF it didn't, please give more details about your question. I'm not quite sure what but I get and extra view from somewhere met, but it sounds like something I encountered before I found this solution.