i am making a customized back button which works exactly as a real back button does. below is my code
UIButton *cusBack = [UIButton buttonWithType:101];
[cusBack setTitle:#"Back" forState:UIControlStateNormal];
[cusBack addTarget:self action:#selector(clickBack) forControlEvents:UIControlEventTouchUpInside];
self.view addSubView:cusBack;
and here is my selector:
-(void)clickBack{
PrevPage *pPage = [[PrevPage alloc] init];
[self.navigationController pushViewController:pPage animated:YES];
[pPage release];
}
actually, it works but the direction it creates is from RIGHT to LEFT. but I want the page to move from LEFT to RIGHT since it goes back to the recent page
thank you!
If you want to have the same behavior as the back button you should try another approach:
-(void)clickBack{ //Your presenting view controller will always be the last view controller on the stack.
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-1] animated:YES];
}
Also, if you need to do some changes to the previous view controller, all you need to do is import it's header file and then you can use it's properties and public methods before popping the view controller.
#import "MyPreviousViewController.h"
...
-(void)clickBack{
[self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-1].title = #"Change title for previous view controller";
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-1] animated:YES];
}
Currently, your back button doesn't work as the real back button does, because, instead of popping the last view controller off the stack(also releasing the objects), you actually keep pushing new view controllers on the stack. You might have some issues if this stack gets too big.
Related
need help to change the text for the left navigation button in ios8
tried
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"My Text" style:UIBarButtonItemStylePlain target:nil action:nil];
and
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"My Text" style:UIBarButtonItemStyleBordered target:nil action:nil];
[[self navigationItem] setBackBarButtonItem:backButton];
Please help
UIButton *buttonLeft = [UIButton buttonWithType:UIButtonTypeCustom];
[buttonLeft addTarget:self action:#selector(buttonLeftAction) forControlEvents:UIControlEventTouchUpInside];
[buttonLeft setFrame:CGRectMake(0, 0, 70, 20)];
[buttonLeft setTitle:#"YourTitle" forState:UIControlStateNormal];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:buttonLeft];
Try above code.
need help to change the text for the left navigation button
That's very confused, because the left navigation button and the back button are two completely different things. So you say "left navigation button" but then what you set is the back button. Thus it's impossible to be sure what you're really trying to do. And moreover, the left button and the back button conflict with one another - by default, they will not both appear. So you have to be careful about that too.
I'm going to assume, in this answer, that although you say the left navigation button, you don't mean it - you mean the back button. And that the top view controller has no left button.
Assuming that's the case, the thing to keep in mind here is that when the back button is showing, it is not the current view controller's navigation item whose back button this is, but the view controller below it in the stack. That is, the back button belongs the back item's navigation item.
Thus, that is the view controller that needs to modify its navigation item's back item, and it needs to do it before another view controller gets pushed onto the stack - preferably much earlier, in its own viewDidLoad.
Thus, this code (from my book) will work if run in the viewDidLoad of the correct view controller:
UIBarButtonItem* b =
[[UIBarButtonItem alloc] initWithTitle:#"Go Back"
style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = b;
But of course if you mean the left bar button item after all, then forget all that. If you mean the left bar button item, then the problem is not that you've got the wrong view controller but that you've got the wrong bar button item!
Is there a way to change the "parent" of a view controller so you can specify which view controller the back button will segue to without creating a custom back button?
Or is the only way to create a custom back button with a custom action?
If you have access to the navigation controller, you could manually insert a view controller in to its stack of view controllers [self.navigationController setViewControllers:] before the current view controller. That would allow the navigation controller to perform its regular actions yet still navigate back to your desired view controller.
Try To create a custom button like
UIBarButtonItem * buttonBack = [[UIBarButtonItem alloc] initWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Back" ofType:#"png"]] style:UIBarButtonItemStylePlain target:self action:#selector(onBackClick:)];
[self.navigationItem setLeftBarButtonItems:#[buttonBack] animated:YES];
and make a method..
- (IBAction)onBackClick:(id)sender
{
// your code
// Write your code what you want to do...
}
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.
I have a PopoverController view that allows a user to download a file. On button press, the popOver view will expand in size, display download status, and the main view controller will be obscured by an unhidden "cover" view that has been added to the PopoverController's "passThroughViews" property so that the user can not accidentally dismiss the pop over while the file is downloading.
My problem is that, in storyboards, my main viewController is embedded in a Navigation Controller. I can't seem to cover the navigation controller's bar with a view in the storyboard, and if the user presses anywhere on the navigation bar then the popover will disappear and the user will lose the download's progress bar.
How do I either cover up the navigation bar with my "cover" view, or how do I add the navigation bar's view to my popOverController's passThroughViews?
Opening the Popover from the main viewController:
- (IBAction)openDataOptionsPopOver:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
PopOverViewController *optionsWindow = [storyboard instantiateViewControllerWithIdentifier:#"dataOptions"];
self.popUp = [[UIPopoverController alloc] initWithContentViewController:optionsWindow];
[self.popUp setDelegate:self];
[nextNavButton setEnabled:NO]; //Disabling barButtonItem on the navigationController
optionsWindow.containerPopOver = self.popUp; //Pointer to the popover, to resize it later.
optionsWindow.coverView = self.coverView; //Pointer to the coverView, to (un)hide later
[popUp presentPopoverFromRect:[sender frame] inView:[sender superview] permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
Setting the passThroughViews property inside of the PopoverViewController:
//Expands the popOver on press of "refreshFileButton" to display progressView
-(void) explodeWindow
{
//setting self.navigationController.view and ...visibleViewController.view here didn't seem to work ...
[containerPopOver setPassthroughViews:[NSArray arrayWithObjects:coverView, nil]];
[containerPopOver setPopoverContentSize:CGSizeMake(600, 400) animated:YES];
[titleBarItem setTitle:#"Downloading File. Please Wait ..."];
[refreshFileButton setHidden:YES];
[progressView setHidden:NO];
[downloadLabel setHidden:NO];
[coverView setHidden:NO];
[progressView setProgress:0.0 animated:NO];
}
I've tried adding self.navigationController.view to passThroughViews with no success--it actually turns out to be a null pointer. And I can't seem to place a UIView at any level in storyboards that will cover all my controls without obscuring the popOver. What am I missing here? And thanks for reading.
Edit:
As Aglaia points out below out, implementing the following, and avoiding passThroughViews, is probably the best way to do this.
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
//Don't dismiss our popover when the view covering our controls is present
if([coverView isHidden]){
return YES;
}else{
return NO;
}
}
Maybe there is something I am missing, but why don′t you just implement a new view controller with its navigation bar set to none and present it modally on button press? Then when the download is finished you just dismiss the view controller.
If you want the user to see the underlying view you can use a UIAlertView instead.
Alternatively set you view controller as the delegate of the popover controller and forbid the user to dismiss your popover on touch outside through
- (BOOL) popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return NO;
}
Then when you want to dismiss it call dismissPopoverAnimated:
to cover the whole screen including navigation bar:
[myView setFrame:[[UIScreen mainScreen] bounds];
[self.navigationController.view addSubview:myView];
Alright, so I made a popover from my main view and all that good stuff. But I want to have my popover call an action in my main view when a button within the popover is pressed.
MainView *mainView = [[MainView alloc] initWithNibName:#"MainView" bundle:nil];
[mainView doStuff];
The "dostuff" function changes some elements within the view. For example, the color of the toolbar is supposed to be changed. I've put a print command and the print command executes. But for some reason, the toolbar won't change color.
I've imported the header of MainView into the popover.
I did an #class thingy for MainView in my popover.
doStuff is declared in MainView's header.
The IBOutlets are declared too, and connected.
Any ideas?
Well its disappointing that we have no direct method that can be used to check in which view (view controller) the popover is shown. The thing that I am doing in tabbased application is:
New_iPadAppDelegate *appDel = (New_iPadAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *viewConts = [(UINavigationController *)[[appDel tabBarController] selectedViewController] viewControllers];
MainViewController *viewController = (MainViewController *)[viewConts lastObject];
if([[viewController popoverController] isPopoverVisible]){
[viewController doStuff];
}
Hope this helps,
I know this is not the best way, hoping apple thinks about this issue, or if somebody has devised a work around.
Thanks,
Madhup