iOS - backbarButtonItem: Canceling back? - iphone

I have a backbarButtonItem in ViewController2 and when the screen goes back to its parent viewcontroller, ViewController1, I want to ask the user if he is ready to go back. If he's not ready, I want to give him an option to stay in ViewController. So ask something like - "Are you ready to leave this screen? - YES or NO"
I know that backbarButtonItem cannot call 'action' as defined in Apple doc. Do you have any good solution?

I would add your own custom leftBarButtonItem to the navigation item, and add whatever action method you want to it. It won't have the same look as the standard back button, but I think that's a good thing -- users expect that the standard button will have a standard behavior. Using a regular rectangular button will alert the users that something different is going on.

Write this in in view didLoad method:
UIImage* myimage = [UIImage imageNamed:#"ButtonImage.png"];
CGRect backFrame = CGRectMake(0, 0, 80, 30);
backButton = [[UIButton alloc] initWithFrame:backFrame];
[backButton setBackgroundImage:myimage forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(MyBtnclicked)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *btn = [[UIBarButtonItem alloc]initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = btn;
and then write ibaction as follows
-(IBAction)MyBtnclicked
{
UIAlertView *av=[[UIAlertView alloc] initWithTitle:nil message:#"Do you really want to Go back" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes",nil];
[av show];
}

One approach would be to subclass the UINavigationController object and override the popViewController:animated: method. You can then decide, based on the user's response, whether to call super's popViewController:animated: or not.

Related

Custom back button for NavigationController for every screen

I have been trying to subclass the UINavigationController class for modifying things like background image, navigation bar size, back button, tittle font and so on.
After a couple of hours and a lot of reading I have understand that I should not subclass the UINavigationController class...
I would like to have specific design and transfer that design to all screens that use my custom NavigationController...
SO far I haven't fount any elegant solution for this, most of the solutions are based on configuring something for showing in the next screen only (next view).
How can I achieve this? Maybe using categories?
Thanks in advance.
I am showing code for custom leftbarbutton of UINavigationcontroller. You can add this code in each view controller and for both button( right and left)
leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
[leftButton setImage:[UIImage imageNamed:#"Yourcutomeimage.png"] forState:UIControlStateNormal];
leftButton.frame = CGRectMake(0, 0, 30, 30);
[leftButton addTarget:self action:#selector(youraction:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:leftButton]autorelease];
//or
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:leftButton]autorelease];
Hope, this will help you..
Yes #Nit is right, this is the way to customize the UINavigationController, but if you don't want to do it for every UIViewController you have, you can create a UIViewControllerBase class, which is a subclass of UIViewController and in viewDidLoad method, set all your buttons the way #Nit has described and then make every UIViewController you have to be a subclass of your UIViewControllerBase class.
If you want to add a custom back button to uinavigationcontroller you should use navigationItem.backBarButtonItem and implement it in the class where you initialize the uinavigationcontroller.
Sample :-
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"btnImage.png" style:UIBarButtonItemStyleBordered target:youtarget action:#sel(your action)];
self.navigationItem.backBarButtonItem = backButton; [backButton release];
I have outlined my solution in this answer: https://stackoverflow.com/a/16831482/171933
Basically, you create a category on UIViewController and call one single method in every viewWillAppear method of your view controllers.

UIActionSheet with UIPickerView and Done, Next, Previous buttons

i am trying to implement an action sheet that contains a picker view and a segmented control bar with a previous button, next button and done button like the image as follows http://imgur.com/8wVMy. I currently am able to make it look like this http://imgur.com/AXn6H. I was wondering if someone could help me get the picker view to sit on the bottom and just make it look a little better. Thanks for any help.
Unless you're targeting very old versions of iOS (i.e. versions earlier than 3.2), the best way to do it is to take a completely different approach.
As of 3.2, any UIResponder (which includes all UIViews) can return a UIView from its inputView property to show that view instead of the keyboard when the view becomes the first responder. This even works for views that normally don't become first responder or don't display the keyboard at all. It's simple:
Design your popup view, as you would any other view.
Ensure that your widget view returns YES from canBecomeFirstResponder.
Ensure that your widget view returns an instance of your popup view from inputView.
More details are available in the documentation.
Also, BTW, if you're on an iPad you should probably use a UIPopoverController to display a UIPickerView instead of either of these methods. Apple may actually require this if you intend to get your app in the app store.
The next and previous buttons are actually showing your images to segmentedController Within a toolbar. To get it You have to define the segmentedController and UIToolbar on. H. Next add the DataSource and UIPickerView
Then in the viewDidLoad create objects and define Their properties. For example:
if (keyboardToolbar == nil) {
keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
[keyboardToolbar setBarStyle:UIBarStyleBlackTranslucent];
segControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Anterior", #"Siguiente", nil]];
[segControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[segControl setTintColor:[UIColor blackColor]];
segControl.frame = CGRectMake(5, 7, 150, 33);
segControl.momentary = YES;
[segControl addTarget:self action:#selector(segSelected:) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *aceptar = [[UIBarButtonItem alloc] initWithTitle:#"Hecho" style:UIBarButtonItemStyleDone target:self action:#selector(cerrarTeclado:)];
//aceptar.width = 70.0f;
[keyboardToolbar setItems:[[NSArray alloc] initWithObjects: extraSpace, aceptar, nil]];
[keyboardToolbar addSubview:segControl];
}

how to determine that the navigation bar's back button has been clicked and then showing a alert

working on a game based project.i am having a view controller as GameScreen.
on the top of Gamescreen having a navigation bar with back button(default).Now if user clicks on back button i have to show alert.
so how to determine "backbutton got clicked."?
any suggestion?
Thanks
In your viewdidload method :
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"back_button.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(cancel:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:button] autorelease];
In the cancel method:
- (IBAction) cancel:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
or show your alert view
}
Otherwise also you can just override the method if you do not want a custom back button.
Your UINavigationBarDelegate has got a nice method for that, called shouldPopItem.
You can override that in your delegate and show there the alert. This gives you also a chance to cancel the going-back (popping).
Stopping the self.navigationItem.leftBarButtonItem from exiting a view - here you go maddy, answers the question in a different context but same basis -

How to use UISegmentControl to change detailViewController of CoreData

I have implemented a UISegmentControl as the rightBarButton of my detailViewController.
This view controller displays that of the information passed through from a UITableView.
This UITableView's cells are populated with CoreData attribute values.
What I want to do is enable the user to go up and down in the list via the detailViewController. Instead of having to make the user have to go back to the rootViewController, they'll gain the ability to scroll through via the UISegmentControl.
I currently have this in my detailViewController.m
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Setting up UISegmentedControl
// Segmented Control - Custom right bar button with a view
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:
[NSArray arrayWithObjects:
[UIImage imageNamed:#"arrowdown.png"],
[UIImage imageNamed:#"arrowup.png"],
nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(0, 0, 75, 30);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.momentary = YES;
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[segmentedControl release];
self.navigationItem.rightBarButtonItem = segmentBarItem;
[segmentBarItem release];
}
This is then attached to the following method, for detecting the tapped control.
- (void)segmentAction:(id)sender
{
UISegmentedControl* segCtl = sender;
// the segmented control was clicked, handle it here
if([segCtl selectedSegmentIndex]==0){
NSLog(#"You clicked the down arrow - the segment clicked was %d", [segCtl selectedSegmentIndex]);
}else {
NSLog(#"You clicked the up arrow - the segment clicked was %d", [segCtl selectedSegmentIndex]);
}
}
I am also curious as to whether or not anyone knows how to detect whether or not there is anymore to go to. So say, if the note loaded is in the first position, then the down arrow is disabled, and if the note loaded is in the last position, the up arrow is disabled. Is this even possible?
Any help would be greatly appreciated.
I'd suggest you to create a formal protocol MyDataSource which provides methods for accessing the data. As a minimum, there must be a method to get number of data objects and object for a specified index.
In your DetailViewController you should have a reference to an object which conforms to MyDataSource. I'd recommend you to use instance of RootViewController as a data source for DetailViewController.
You should also keep track of index of the object that is currently displayed in DetailViewController and update UI appropriately.

How can I modify the target of the default Back button on iphone?

I want to have the default shape of the back button, but that makes my program enter a loop at some point.
The code is this for modifying the text of the back button, written before the initialization of the view.
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"Back" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
[newBackButton release];
can I also change the target to another view? I really need that default shape and I don't know how else to get it. Thanks!
The UINavigationController does not work that way, you'll need to make a custom UIBarButton with an image.
If you want to customize the right-button in the navigation controller you usually set the backBarButtonItem on the parent view controller, i.e. the one you are going back to.
parentViewController.navigationItem.backBarButtonItem =
[[[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:nil action:nil] autorelease];
There is a solution to modify the target of the back button on this blog. The key idea is to subclass UINavigationController and override the popViewControllerAnimated: method. First paste in your custom code and then call [super popViewControllerAnimated:animated] at the end.
I have verified that this still works fine in SDK 4.3.