ModalViewController Without Dimming / Disabling current viewcontroller - objective-c

I am displaying aNavController as a modalViewController in a specific frame CGRectMake(40,50, 400, 500). Which is working fine. Now I have a button in self (viewcontroller on which modalViewController is presented), on pressing that button I need to display some message on aNavController. But problem is when I am presenting a modalViewController. Whole screen area got dimmed/disabled. So, not able to touch/click that button in self.
Here is my code to present a view controller. I thought, I am missing something here. Please Help. Thanks in advance.
aNavController.modalPresentationStyle = UIModalPresentationFormSheet;
anavController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:aNavController animated:YES];
aNavController.view.superview.frame = CGRectMake(40,50, 400, 500);

presentModalViewController create a modal dialog. When modal view controller is up, users can't do any thing on parent view until the the modal view is dismissed.

The problem is you're instantiating a UIAlertView at the same time as the presentModalViewController call your modal view in UIAlertView's delegate method clickedButtonAtIndex.
Like so:
- (IBAction)clickedMyButton:(id)sender
{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: #"Title"
message: #"Message"
delegate:self
cancelButtonTitle:#"Close Button"
otherButtonTitles:#"Modal Button", #"Some Other Button", nil];
[alertView show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"User Selected Cancel");
}
else if (buttonIndex == 1) {
NSLog(#"Modal Button Clicked");
aNavController.modalPresentationStyle = UIModalPresentationFormSheet;
anavController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:aNavController animated:YES];
aNavController.view.superview.frame = CGRectMake(40,50, 400, 500);
}else {
NSLog(#"Some Other Button Clicked");
}
}
Or, if you wish for your UIAlertView to show on top of your navigation controller, ignore the above and simply wait to call your alert until the navigation controllers - (void)viewDidAppear:(BOOL)animated method.
In addition, I recommend you change your frame to stay within the bounds of the screen unless absolutely necessary. ex: CGRectMake(40, 50, 320, 480);

Finally, I am able to do workaround the things which work same way as a UIModalPresentationFormSheet.
I added the aNavController as a subview to the [[UIApplication sharedApplication] keyWindow] and which solves my all the problems.
Thank you all for your comments.

Related

Pop controller after back bar button is pressed

I have a UINavigationController ans a chain of 3 simple controllers. Each one has a button. When press a button a next controller is Pushed. ViewController1 -> ViewController2 -> ViewController3. When I push a back button on the 3rd view i want to move to the first view. Using of backBarButtonItem is obligatory. Here is the code for second controller:
#import "ViewController2.h"
static BOOL isBackButtonPressed;
#implementation ViewController2
- (void)viewDidLoad {
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:#"back from 3" style:UIBarButtonItemStyleBordered target:nil action:nil];
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
if (isBackButtonPressed) {
[self.navigationController popViewControllerAnimated:YES];
} else {
isBackButtonPressed = YES;
}
[super viewWillAppear:animated];
}
#end
But when I press back button on the third view I return to the second view instead of the first view. Could you help me to return to the first view pressing back button on the third view.
I tried suggestions from answers but they don't help.
Adding a selector to backBarButtonItem doesn't help because it is never called.
Adding a [self.navigationController popToRootViewControllerAnimated:YES] in viewWillDisappear methos also doesn't work. I don't know why. I think that the actual problem is how backBarButtonItem works.
Any other suggestions?
The behaviour I try to achieve exists in the calendar on iPhone. When you rotate iPhone to landscape you get to the weeek view. Then go to the event details, and rotate to the portrait. When you press back button you will get to a day view not to a week view, so a controller with weekview is skipped.
After countless number of tries my solution was simply not use backBarButtonItem! As whatever i do it always goes to previous viewController instead of calling its selector
Instead I use only leftBarButtonItem for navigation, as it guarantees calling my action.
Here an example
UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 27, 22)];
[backButton setImage:[UIImage imageNamed:#"backbutton"] forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(backButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
This certainly calls backButtonPressed action.. This works both for IOS 6 and 7
No need to register a new selector for the back button, just do:
-(void)viewWillDisappear{
if ( [self.navigationController.viewControllers containsObject:self] )
//It means that the view controller was popped (back button pressed or whatever)
//so we'll just pop one more view controller
[self.navigationController popViewControllerAnimated:NO];
}
in your ViewController3 viewWillDisappear method
Try using this in your third view controller, this way you check if you have pressed the back button and directly pop to the root view controller which as you stated is your first view controller.
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
[self.navigationController popToRootViewControllerAnimated:YES];
}
[super viewWillDisappear:animated];
}
I had the same problem as you beofre and fixed it like this:
You can capture the back button on the ViewController3 and before poping the view, remove ViewController2 from the navigation stack like this:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:#"back from 3" style:UIBarButtonItemStyleBordered target:self action:#selector(customBackPressed:)];
}
-(void)customBackPressed:(id)sender {
NSMutableArray *allViewControllers = [NSMutableArray arrayWithArray: navigationController.viewControllers];
for (UIViewController *vc in viewControllers)
{
// If vc is ViewController2 type, remove it
}
navigationController.viewControllers = allViewControllers;
[self.navigationController popViewControllerAnimated:YES];
}
Because ViewController2 is not in the stack anymore, it will jump to ViewController1.
Also, if ViewController1 is the root view controller, you can just do:
[self.navigationController popToRootViewControllerAnimated:YES];

UIAlertView button to display viewController

I've been looking all over the internet for a solution to this problem, yet to find one that I can understand. So here it goes.
I have my iOS application, on which on the first launch of the application, will display a UIAlertView. I want one of the buttons to send the user to a new viewController to view some essential information.
I have gotten my UIAlertView configured properly, here's the code for the actionSheet:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
{
//Code to open a new viewController???
}
if (buttonIndex == 1)
{
//User can exit the application if they do not wish to continue
exit(0); }
}
}
I have a viewController created named webViewViewController, that's what I want users to reach when they tap the first button. Any ideas on how to do this? I have ARC disabled, other 'solutions' i've come across keep giving me errors.
Thanks all, would appreciate some guidance here.
If your current viewcontroller is in a Navigation Controller:
UIViewController *myViewController = [[UIViewController alloc] init];
myViewController.title = #"My First View";
//to push the UIView.
[self.navigationController pushViewController:myViewController animated:YES];
And never use exit(0)!
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
{
NewViewController *controller=[[NewViewController alloc]initWithNibName:#"NewViewController" bundle:nil];
self.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[self presentViewController:controller animated:YES completion:nil];
}
drasick has given sufficient answer but if you need to use model view controller refer above.
Use:
UIViewController *yourViewController = [[UIViewController alloc] init];
[self.navigationController presentModalViewController:myViewController animated:YES];
to push a modalViewController.(This is depriciated in iOS 6, but will work)

open a uiviewcontroller from uialertview button

I want to open a UIViewController if a UIALertView Button is pressed.
I have the code for that. However, the uiviewcontroller is not being opened :(
I am sure the uialertview is working fine and all. and the code for the uiviewcontroller is fine as well. (it works when called from other places).
Any help ?
Thanks.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) //Yes, Sign Me Up!
{
NSLog(#"0");
ViewerWebController *web = [[ViewerWebController alloc] initWithURL:[NSURL URLWithString:#"http://www.funimation.com/"]];
[web setShowToolbar:YES];
[self.navigationController pushViewController:web animated:YES];
[web release];
}
else if (buttonIndex == 1) //Remove from List
{
NSLog(#"1");
[[NSUserDefaults standardUserDefaults] setBool:false forKey:#"subscribeButtonOption"];
[_tableView reloadData];
}
else if (buttonIndex == 2) //"Maybe Later"
{
NSLog(#"2");
}
}
The alert view doesn't have a navigation controller. You would need to keep a reference to the navigation controller you want to push the view controller on to.
This may work..
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
if (buttonIndex == 0)
{
YourRootNavigationController *navController = [YourRootNavigationController sharedInstance]; // singleton
[navController pushViewController:YOUR_CONTROLLER animated:YES];
}
else
{
NSLog(#"cancel");
}
}
Use didDismissWithButtonIndex rather clickedButtonAtIndex.
The former is invoked after the UIAlertView has been removed from the screen hierarchy, while the latter occurs while the UIAlertView is still on screen. While on screen, UIAlertView alters the nature of the app; that means bad things happen when trying to push views to the nav controller.
This misuse of clickedButtonAtIndex seems to be common misinformation floating around the internet and StackOverflow. Cost me hours of frustration.

don't want to dismiss UIPopover

i am using this following code to display a popover in my View
imagePopOver = [[UIPopoverController alloc];
initWithContentViewController:self.photoLibraryImageCollection.imagePickerController];
imagePopOver.popoverContentSize = CGSizeMake(185,675);
imagePopOver.delegate = self;
[imagePopOver presentPopoverFromRect:CGRectMake(600,0, 140, 800)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
it working fine however if we click any other part of myView ,this displayed popover is dismissing.can any one tell me how can i avoid this problem. i don't want to dismiss it at any time.can any one tell me how can do it.
In the popover's delegate (your viewController, probably), implement
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController {
return NO;
}
Don't forget to set the delegate!
just wrote the below code at the time of popover initialization.
myPopOver.passthroughViews = [NSArray arrayWithObject:self.view];
in the above code will not dismiss your popOver and we can work with our View.
if you don't want to dismiss UIpopover only at the time of a textBox edit,simply write
myPopOver.passthroughViews = [NSArray arrayWithObject:self.textBox];

NavigationController is not popping the Pushed View on Back button

Having a simple Navigation Controller in place (starting the Navigation Based Application project) I created a new View with a XIB file.
on my HomeViewController (Home screen with all options as UIButton's I have:
#implementation HomeViewController
-(IBAction) optionChoosed:(UIButton *)button
{
NSString *msg = [NSString stringWithFormat:#"Button: %d", button.tag];
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Hi" message:msg delegate:nil cancelButtonTitle:#"Go away" otherButtonTitles:nil];
switch (button.tag) {
case 13:
// Simple Search
[self loadSimpleSearch]; break;
default:
[alert show];
break;
}
[alert release];
}
-(void)loadSimpleSearch
{
SimpleSearchViewController *controller =
[[SimpleSearchViewController alloc] initWithNibName:#"SimpleSearchViewController" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
[controller release];
}
witch works great!
it Pushes the View into the front of the stack!
Now, because in my 2nd view SimpleSearchViewController I have self.title = #"myTitle"; I get the Title in the NavigationBar as well the back button (as I have the same setting on the HomeViewController)
I thought that the NavigationViewController would handle the pop of the current view, but it does not.
What do I have to do, to pop the SimpleSearchViewController?
Where do I use [self.navigationController popViewControllerAnimated:YES];
as the view continues there, and ViewDidUnload is never called.
My idea was that this should be handle in the first ViewController, the HomeViewController but I have no idea what is the method I should hook to, and I read the documentation and I can't figure it out :-/
Any help is greatly appreciated, thank you.
HomeViewController
alt text http://cl.ly/XNS/Screen_shot_2010-04-21_at_22.38.51.png
SimpleSearchViewController
alt text http://cl.ly/YDw/Screen_shot_2010-04-21_at_22.40.00.png
SimpleSearchViewController after pressing the Back button
alt text http://cl.ly/XLO/Screen_shot_2010-04-21_at_22.40.21.png
To add the image from a comment that asks if HomeViewController as the root controller for the NavigationViewController
Not sure if this helps but when implementing navigationItem in code, if you don't call the super the popping functionality will not be present
-(UINavigationItem*) navigationItem
{
UINavigationItem* item = [super navigationItem];
item.title = #"search";
return item;
}