I need to access to parentViewController after presentMoalViewController.
This is my method that I call in the firstViewController to view the secondViewController:
- (void)viewData {
SecondViewController *viewCtrl = [self.storyboard instantiateViewControllerWithIdentifier:#"select_data"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewCtrl];
navigationController.navigationBar.barStyle = UIBarStyleBlack;
UIBarButtonItem *saveButton = [[[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:viewCtrl action:#selector(saveData)] autorelease];
viewCtrl.navigationItem.rightBarButtonItem = salvaButton;
UIBarButtonItem *undoButton = [[[UIBarButtonItem alloc] initWithTitle:#"Undo" style:UIBarButtonItemStyleBordered target:viewCtrl action:#selector(backView)] autorelease];
viewCtrl.navigationItem.leftBarButtonItem = annullaButton;
[self presentModalViewController:navigationController animated:YES];
}
When I click on saveButton, I try to access to parentViewController in this way, but it not work:
- (void) saveData {
FirstViewController *parentView = (FirstViewController*)[[self navigationController] presentingViewController];
parentView.dataString = [[NSMutableString alloc] initWithFormat:#"new string"];
[parentView performSelectorInBackground:#selector(myMethod) withObject:nil];
[self dismissModalViewControllerAnimated:YES];
}
It would be much better if you used a delegate/protocol in your second viewController that the first viewController could set itself as. You can find more info here Pass data back to the previous controller or simply doing a search. This design pattern is used virtually everywhere in iOS programming.
The big advantage is that then your second viewController becomes independent of whoever presented it, and can be easily reused. The technical term would be 'decoupling'.
Last time I did this I used notifications:
[[NSNotificationCenter defaultCenter] postNotificationName:#"saveData" object:dataString];
in your parent vc view didload:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(saveDataNow:) name:#"saveData" object:nil];
For navigationController you can declare a property called something like myController, then you have to initiate your navigationController like this:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewCtrl];
navigationController.navigationBar.barStyle = UIBarStyleBlack;
navigationController.myController = self;
UIBarButtonItem *saveButton = [[[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:viewCtrl action:#selector(saveData)] autorelease];
viewCtrl.navigationItem.rightBarButtonItem = salvaButton;
UIBarButtonItem *undoButton = [[[UIBarButtonItem alloc] initWithTitle:#"Undo" style:UIBarButtonItemStyleBordered target:viewCtrl action:#selector(backView)] autorelease];
viewCtrl.navigationItem.leftBarButtonItem = annullaButton;
[self presentModalViewController:navigationController animated:YES];
In your parentViewController Class you declare your Method
- (void) saveData {
FirstViewController *parentView = (FirstViewController*)[[self navigationController] presentingViewController];
parentView.dataString = [[NSMutableString alloc] initWithFormat:#"new string"];
[parentView performSelectorInBackground:#selector(myMethod) withObject:nil];
[self dismissModalViewControllerAnimated:YES];
}
In your navigationController you can then call [myController saveData];
This should work, if you have any questions, feel free to ask!
You can access your parent view controller using following-
- (void) saveData {
NSMutableArray *activeControllerArray = [self.navigationController.viewControllers mutableCopy];
FirstViewController *parentView;
for(int i = 0, i <[activeControllerArray count], i++) {
if([[activeControllerArray objectAtIndex:i] isKindOfClass:[FirstViewController class]) {
parentView= [activeViewController objectAtIndex:i];
break;
}
}
parentView.dataString = [[NSMutableString alloc] initWithFormat:#"new string"];
[parentView performSelectorInBackground:#selector(myMethod) withObject:nil];
[self dismissModalViewControllerAnimated:YES];
}
Related
Have a mainviewcontroller and on it have UIToolbar which has a UIBarButtonItem Info which shows UIViewcontroller modally.
Now when pressing Infobutton it is showing UIViewController modally which has UITextView but not showing UINavigationController with Done button.
I am not able to figure it out what i am missing in my code.
This is how i am showing UITextView and NavigationController in UIViewController modally.
#import "ModalViewController.h"
#import <QuartzCore/QuartzCore.h>
#implementation ModalViewController
#synthesize textView;
#synthesize navBar;
#synthesize navigationController;
#synthesize delegate;
-(void)dealloc
{
[textView release];
[navBar release];
[navigationController release];
[super dealloc];
}
- (void) viewDidLoad
{
[super viewDidLoad];
self.title = #"Info";
UINavigationController *navigationController = [[UINavigationController alloc]init];
//initWithRootViewController:viewController];
self.navigationController.navigationBar.tintColor = [UIColor brownColor];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(Done:)] autorelease];
self.textView = [[[UITextView alloc] initWithFrame:CGRectMake(0, 0, 320, 416)]autorelease];
self.textView.textColor = [UIColor whiteColor];
self.textView.font = [UIFont fontWithName:#"Georgia-BoldItalic" size:14];
//self.textView.delegate = self;
self.textView.backgroundColor = [UIColor brownColor];
self.textView.layer.borderWidth = 1;
self.textView.layer.borderColor = [[UIColor whiteColor] CGColor];
self.textView.layer.cornerRadius = 1;
self.textView.textAlignment = UITextAlignmentCenter;
self.textView.text = #"This is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.
self.textView.editable = NO;
//[self.view addSubview:navigationController.view];
[self.view addSubview: self.textView];
//[navigationController release];
}
And this is how UIViewController presented modally
//Create a final modal view controller
UIButton *modalViewButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[modalViewButton addTarget:self action:#selector(modalViewAction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *modalBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:modalViewButton];
self.navigationItem.rightBarButtonItem = modalBarButtonItem;
- (void) modalViewAction:(id)sender
{
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]autorelease];
//self.viewController = [[ModalViewController alloc] init];
[self.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
//ModalViewController *myModalViewController = [[ModalViewController alloc] init];
//UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myModalViewController];
//navigationController.navigationBar.tintColor = [UIColor brownColor];
_viewController = [[ModalViewController alloc] init];
//[navigationController pushViewController:_viewController animated:YES];
[self presentModalViewController:self.viewController animated:YES];
//[self.view addSubview:navigationController.view];
//[navigationController release];
[myModalViewController release];
}
I will appreciate if you can figure out what i m doing wrong or missing in my code.
Thanks a lot.
This seems like a needlessly convoluted way of displaying the new controller. In my apps, I do it like this:
//this function displays (modally) view controller nested inside a navcontroller
- (void) showModalController
{
YourViewController * ecreator = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil];
UINavigationController * navcontrol = [[UINavigationController alloc] initWithRootViewController: ecreator];
[self presentModalViewController: navcontrol animated:YES];
[navcontrol release];
[ecreator release];
}
Now you want to do the graphical setup (navbar color etc) in the initWithNib and/or viewDidLoad functions of the YourViewController.
#synthesize navigationController;
so navigationController is your class member variable.
in the function
- (void) viewDidLoad
you declare a local variable
UINavigationController *navigationController
Please notice that the second navigationController is different from your member variable navigationController .
So, inside viewDidLoad you need to create object of your member variable navigationController. Not the local variable navigationController.
Do not RE-declare navigationController in viewDidLoad. Instead, create the object using member variable like:
navigationController = [[UINavigationController alloc]init];
Try this, it worked great for me. I had the exact same problem
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#“segue_name"])
{
UINavigationController *nav = [segue destinationViewController];
ExampleViewController *exampleVC = (ExampleViewController *) nav.topViewController;
//Setup any properties here and segue
}
}
I'm using presentModalViewController to go from view controller to view controller. Right now the animations are up and down when it goes from one view to another. Can I change it to right and left? I did not see any settings for this in the method presentModalViewController
Ted
Try this before presenting the modal vc:
[sampleViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
// or..
// [sampleViewController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
// or..
// [sampleViewController setModalTransitionStyle:UIModalTransitionStylePartialCurl];
See the modalTransitionStyle Property of a UIViewController - Here are the Reference docs
You can make convenience methods for all styles like so (from Modal View Controller Example):
- (IBAction)showDefault:(id)sender {
SampleViewController *sampleView = [[[SampleViewController alloc] init] autorelease];
[self presentModalViewController:sampleView animated:YES];
}
- (IBAction)showFlip:(id)sender {
SampleViewController *sampleView = [[[SampleViewController alloc] init] autorelease];
[sampleView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:sampleView animated:YES];
}
- (IBAction)showDissolve:(id)sender {
SampleViewController *sampleView = [[[SampleViewController alloc] init] autorelease];
[sampleView setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:sampleView animated:YES];
}
- (IBAction)showCurl:(id)sender {
SampleViewController *sampleView = [[[SampleViewController alloc] init] autorelease];
[sampleView setModalTransitionStyle:UIModalTransitionStylePartialCurl];
[self presentModalViewController:sampleView animated:YES];
}
Hello guys,
I trying to make a app with tabbar controller and navigation controller.
But i get some problems... When i try to popViewController on my second view, the app crash.
Some one knows what's going on?
My Delegate:
// -- PranchetaAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:1];
PlayersViewController* playersViewController = [[PlayersViewController alloc] initWithTabBar];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:playersViewController];
[localControllersArray addObject:self.navigationController];
[self.navigationController release];
self.tabBarController.viewControllers = localControllersArray;
[self.window addSubview:self.tabBarController.view];
[self.window makeKeyAndVisible];
[self.navigationController release];
[localControllersArray release];
return YES;
}
My First View:
// -- PlayersViewsController.m
- (id)initWithTabBar {
if (self)
{
self.title = #"Players";
self.tabBarItem.image = [UIImage imageNamed:#"PlayersTabBarIcon.png"];
CustomNavigationBarButton *addButtonView = [[CustomNavigationBarButton alloc] initWithImage:#"AddButton.png" withSelected:#"AddButtonSelected.png"];
[addButtonView addTarget:self action:#selector(gotoCreatePlayers) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithCustomView:addButtonView];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
[addButtonView release];
}
return self;
}
- (void)gotoCreatePlayers {
CreatePlayersViewController *createPlayer = [CreatePlayersViewController new];
[self.navigationController pushViewController:createPlayer animated:YES];
[createPlayer release];
}
When i push my second view, i try to go back into the navigation. But the app crash...
Error appointed:
// -- main.m
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Thanks guys!
try this:
change:
CreatePlayersViewController *createPlayer = [CreatePlayersViewController new];
to:
CreatePlayersViewController *createPlayer = [CreatePlayersViewController alloc];
also if there are any init methods to call than it should look like this
CreatePlayersViewController *createPlayer = [[CreatePlayersViewController alloc]init];
try somthing like this:
ADD THIS TO THE .h FILE: CreatePlayersViewController *createPlayer
then replace your code above with this:
if (createPlayer ==nil) {
CreatePlayersViewController *nextView = [[CreatePlayersViewController alloc] initWithStyle:UITableViewStylePlain];
self.createPlayer = nextView;
[nextView release];
}
self.meetTheTeam.view.hidden = NO;
[self.navigationController pushViewController:self.meetTheTeam animated:YES];
I have this code to present a popover:
- (UIPopoverController *)favoritesPopover
{
if (!favoritesPopover)
{
FavoritesViewController *fvc = [[FavoritesViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:fvc];
[fvc release];
favoritesPopover = [[UIPopoverController alloc] initWithContentViewController:navController];
[navController release];
favoritesPopover.delegate = self;
}
return favoritesPopover;
}
- (IBAction)toggleFavorites:(id)sender
{
if (!self.favoritesPopover.popoverVisible)
[self.favoritesPopoverpresentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
else
[self.favoritesPopover dismissPopoverAnimated:YES];
}
Now when didSelectRow is called in FavoritesViewController, I want the popover to be dismissed. I tried [self dismissPopoverAnimated: YES]; but that isn't recognized.
You need to get a reference to the popoverController in your FavoritesViewController. Setup a popoverController property in FavoritesViewController and then you should be able to dismiss it in the didSelectRow method.
I am displaying a UITableViewController inside of a UITabBarController that is being presented modally:
-(IBAction)arButtonClicked:(id)sender{
//this is a uitableviewcontroller
ARViewController* arViewController = [[[ARViewController alloc] initWithNibName:#"ARViewController" bundle:nil]autorelease];
LeaderBoardTableViewController* lbViewController = [[[LeaderBoardTableViewController alloc] initWithNibName:#"LeaderBoardTableViewController" bundle:nil]autorelease];
lbViewController.title = #"Leaderboard";
arTabBarController = [[UITabBarController alloc] initWithNibName:nil bundle:nil];
arTabBarController.viewControllers = [NSArray arrayWithObjects:arViewController, lbViewController, nil];
arTabBarController.selectedViewController = arViewController;
[self presentModalViewController:arTabBarController animated:YES];
}
In my viewDidLoad for arViewController method I am setting the navigation items:
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
self.clearsSelectionOnViewWillAppear = NO;
self.title = #"AR";
leaderBoardButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemOrganize
target:self
action:#selector(leaderBoardButtonClicked:)];
self.navigationItem.rightBarButtonItem = leaderBoardButton;
}
My navigation bar doesn't appear when it is inside of the UITabBarController, but when I push the view itself I am able to see it.
What am I missing?
Heh, I've been stumped by this too. What you need to do is send the rootViewController.
I've never used a tabBar for anything except on the main screen but ur code will probably look like this:
after arTabBarController.selectedViewController = arViewController;
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController: arTabBarController] autorelease];
[self presentModalViewController: navController animated:YES];
Like I said I haven't done it with a tabBar but I'm pretty sure it will be something along these lines
I needed to add a UINavigationBar:
ARViewController* arViewController = [[[ARViewController alloc] initWithNibName:#"ARViewController" bundle:nil]autorelease];
UINavigationController *arNavController = [[UINavigationController alloc] initWithRootViewController:arViewController];
LeaderBoardTableViewController* lbViewController = [[[LeaderBoardTableViewController alloc] initWithNibName:#"LeaderBoardTableViewController" bundle:nil]autorelease];
lbViewController.title = #"Leaderboard";
UINavigationController *lbNavController = [[UINavigationController alloc] initWithRootViewController:lbViewController];
arTabBarController = [[UITabBarController alloc] init];//initWithNibName:nil bundle:nil];
arTabBarController.viewControllers = [NSArray arrayWithObjects:arNavController, lbNavController, nil];
arTabBarController.selectedViewController = arNavController;
[self presentModalViewController:arTabBarController animated:YES];
There is a simple solution, put setting in view will appear
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
hope it help some newbies;