Add some Operations to the back button of a NavigationViewController - objective-c

I want to force the back button of my navigationViewController to call the dissmissmodalViewController to prevent the fact that the user tap the back button to fast and the app send a message to a deallocated instance... how can I solve?
Thanks

You question feels a bit odd because the back button typically does something like:
[self.navigationController popViewControllerAnimated:YES];
I'm not sure how that is impacting any modal view controllers. If you really need to change its functionality, then you would basically hide the built in back button and replace it with your own custom one kind of like this: (put this in viewDidLoad)
[self.navigationItem setHidesBackButton:YES]; //hide the built in button
//create your new button
UIBarButtonItem *b = [[UIBarButtonItem alloc]initWithTitle:#"new-back-button" style:UIBarButtonItemStyleDone target:self action:#selector(customBackButton:)];
//set the new button
self.navigationItem.leftBarButtonItem = b;
then setup your new method to handle the button push
- (IBAction)customBackButton:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
good luck with your project.

Related

Using the segue from master detail application with custom button.

So, I have a master detail application. So far an object is created at launch and added to the master list, the detail view works fine as well.
What I would like to do, is to let the user add object to the master list by pressing a button. I don´t need a new view for that though, I want to use the standard Detail View for this part.
When the user taps the "Add" button, a new object should be created and then go into the detailed view of that object. I thought, "hey, why not use the standard segue as well?"
So I added a Bar Button Item to the MasterView.
This my code from MasterViewController.m:
-(IBAction)addNewItem:(UIStoryboardSegue *)segue{
if([[segue identifier] isEqualToString:#"showDetail"]){
CoolItem *newItem;
NSDate *today = [NSDate date];
newItem = [[CoolItem alloc]initWithDate:today];
[self.dataController addCoolItemWithItem:newItem];
DetailViewController *detailViewController = [segue destinationViewController];
detailViewController.coolItem = newItem;
}
}
"showDetail" is the identifier of the standard segue that comes with the master detail template.
The result: Nothing! The method is not called at button tap.
I´ve made sure my button is connected to this method, (it does however shows up as a unwind segue in the document outline).
Any ideas on what goes wrong?
I'm not sure what went wrong but I was able to achieve the desired functionality using the following code:
-(void)viewDidload {
...
self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(Add:)];
}
-(IBAction)Add:(id)sender
{
// Create the new item and set it as active
...
[self performSegueWithIdentifier: #"SegueName" sender:self];
}
Hope this helps
Yaron

Instant / Autosave in IOS

For background: I'm a Windows automation and data translation "expert" (or so they say grins) in my day job. I've been dabbling with Objective-C coding off and on since I bought my first Mac in 2004.
I'm working on an IOS app. My data container class knows how to save and load from disc, and each object responds to an instance method of -(void)saveToImpliedFilename{} or -(void)save:(NSString *)filename {}. There's a static call to load the data files from storage and create distinct data objects from them (they're fairly lightweight objects, so I'm not worried about loading several at a time). The app's domain is such that many of them won't ever be loaded at once anyway.
+(NSArray *)loadData {}
That's all working fine and wonderful. In storage the objects are stored as Xml and life is good.
Where I'm having trouble is when trying to modify the tutorials so that two things happen for me:
Quick note: I'm using the tutorial as a basis for POC coding, then I'll go back and start over with the "real" coding, reusing my data objects and some of the other utility I've built along the way.
Here's my list of goals and the issues:
I want the table view to tell the data objects to save at pretty much every "edit" event. The only one I can consistently get to work is reorganizing the table's order. (the save button and adding a new entry works fine)
entering a new entry into the list creates a nice modal editor with a save and a cancel button which work wonderfully. But if I edit an existing entry, I can't reproduce the save buttons' behaviors. Each time I try, the buttons' events no longer fire. I can't figure out where I'm going wrong.
I'm using the "Editable Table View" project from this tutorial series as my basis: http://www.aboutobjects.com/community/iphone_development_tutorial/tutorial.html
In the following code, the [self isModal] test is where the save/cancel buttons are made visible and wired up. Bringing up the new-entry screen is apparently the only time it's modal. I tried wiring this stuff up so that the buttons were created all the time, but again, the events never fire for either one. The next block below is where the editable table view is called explicitly with the NEW functionality, but the nonModal view of the same tableview is called by the select event on the selector table.
So...
// code snipped for the new/modal editor
- (void)viewDidLoad {
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
// If the user clicked the '+' button in the list view, we're
// creating a new entry rather than modifying an existing one, so
// we're in a modal nav controller. Modal nav controllers don't add
// a back button to the nav bar; instead we'll add Save and
// Cancel buttons.
//
if ([self isModal]) {
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self
action:#selector(save)];
[[self navigationItem] setRightBarButtonItem:saveButton];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(cancel)];
[[self navigationItem] setLeftBarButtonItem:cancelButton];
}
// do stuff here to display my object...
}
// this code is called from the selection table to explicitly add a new data object.
- (void)add {
vhAddVehicleViewController *controller = [[vhAddVehicleViewController alloc] initWithStyle:UITableViewStyleGrouped];
id vehicle = [[Vehicle alloc] init];
[controller setVehicle:vehicle];
[controller setListcontroller:self];
UINavigationController *newNavController = [[UINavigationController alloc] initWithRootViewController:controller];
[[self navigationController] presentViewController:newNavController animated:YES completion:nil];
}
// this is where it's called on the table selection to show the same view without the save/cancel buttons.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
vhAddVehicleViewController *controller = [[vhAddVehicleViewController alloc] initWithStyle:UITableViewStyleGrouped];
NSUInteger index = [indexPath row];
id vehicle = [[self vehicles] objectAtIndex:index];
[controller setVehicle:vehicle];
[controller setTitle:[vehicle Vehiclename]];
[[self navigationController] pushViewController:controller animated:YES];
}
I'm assuming the issue is that presenting it makes it modal, where as pushing it doesn't...? That's fine. But when I take out the test for modal to try to keep the buttons working, no joy. The buttons draw and click when tapped, but the events don't fire.
HALP! :-)
Thanks much.
-- Chris (I logged in with my Google account so at the top of the page I'm showing as "user1820796") shrug
You forgot to call [super viewDidLoad];
Update
Try removing the cancel button that goes on the left side when pushing the view controller. See if save starts working. I think the problem is you should not add a left button to the navigation bar when the view controller is pushed.
Which method signature are you using?
- (void)save
{
NSLog(#"Saving");
}
Or
- (void)save:(id)sender
{
NSLog(#"Saving");
}
I still think this was related to push/popping the view rather than presenting the view. I switched it all to presentation and it's working how I want now.
Thanks for the assistance guys. Quite a different paradigm than I'm used to on the GUI stuff, but I'm getting there.
thanks!

Programmatically click the leftbarbutton (back-button) of a pushViewController of the navigationController

I want to click the back button in the navigationBar programmatically in my second view.
It's call it this way:
Archiv *archiv = [[Archiv alloc] initWithNibName:#"Archiv" bundle:nil];
archiv.title = [NSString stringWithFormat:#"Archiv %#", [sender titleForState:UIControlStateNormal]];
[self.navigationController pushViewController:archiv animated:YES];
And now i'm in the Archiv.m and after a specific event i want to get back to the first controller (without clicking the back button) - instead i want to perform the click programmatically.
Is it possible for this case?
Helpful would be to know which method is called if i click on this button, so don't even have to perform the click.
yes you can
this will take you to your first view controller
[self.navigationController popToRootViewControllerAnimated:YES];

Popover not being dismissed when calling dismissPopoverAnimated or clicking once outside of popover

I hope someone can help me with this weird bug. I've got a popover with buttons to perform various actions. There is a toolbar item that must be clicked to bring up the popover. Here is the action method that is called:
-(IBAction)showActions:(id)sender
{
ActionsPopUpController* controller = [[ActionsPopUpController alloc] initWithDelegate:self state:DELETE_ENABLED | FACEBOOK_ENABLED | TWITTER_ENABLED | EMAIL_ENABLED];
_actionsPopUp = [[UIPopoverController alloc] initWithContentViewController:controller];
[controller release];
[_actionsPopUp presentPopoverFromRect:_actionButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
_actionsPopUp.delegate = self;
}
As you can see, I have a property/ivar (actionsPopUp) that retains a reference to the UIPopoverController. This is used later to call dismissPopoverAnimated when I want to dismiss the popover. Here is an example of it's use:
-(void)shareWishToEmail:(id)sender
{
[_actionsPopUp dismissPopoverAnimated:YES];
[[WishCloudService sharedInstance] showMailer:self withItems:[NSArray arrayWithObject:self.item] delegate:self modal:YES];
}
In this method, I dismiss the popover first, and then perform the action associated with the button that was pressed in the popover. Unfortunately, this doesn't appear to work. The action gets performed, but the popover is not dismissed. In addition, it doesn't seem to get dismissed when the user clicks once outside of the popover. But if clicked outside again, it does get dismissed. Another observation is that the first click seems to hide/dismiss the drop shadow of the popover, but not the popover itself. It's the second click that dismisses the popover. However, no amount of calling dismissPopoverAnimated seems to dismiss the popover at all.
I've swapped in UIPopoverControllers that seem to work in other parts of the application, but get the same results, which leads me to believe that it is something specific to the UIView/UIViewController that I'm presenting the popover in. I am creating the view programmatically rather than through a NIB. It escapes me at the moment why I decided to do that, but I don't believe that it should be relevant. Someone please let me know otherwise. Here is my loadView method:
-(void)loadView
{
self.view = [self createView:_item];
self.currentView = self.view;
_wishItemViews = [[NSMutableDictionary dictionary] retain];
[_wishItemViews setObject:_currentView forKey:[NSNumber numberWithInteger:_currentIndex]];
}
I have a currentView property because I need to be able to slide new views in and out, and I'm using CATransition animations to do it. The currentView property is used to swap the views when it performs the transitions. Again, not sure if this is relevant, but I'm including it for completeness and just in case it does make a difference. Hopefully, that's enough information for someone to help point me in the right direction. Or at least prompt some additional questions that might help me think this through. Any help would be greatly appreciated.
Another observation is that the first click seems to hide/dismiss the drop shadow of the popover, but not the popover itself.
It seems you have stumbled upon the rare double-popover. ;-)

UINavigationBar right button not showing up

I am using the following function via a notification to load a right button on my UINavigationBar, and even though I can trace out the button and verify it is allocated, it does not show up...any ideas?
EDIT 4/6/2011, 2:42PM
So, something interesting...the width always reports as 0.0...
- (void)showRightBarButton:(id)sender
{
NSLog(#"Showing button");
UIBarButtonItem *button = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(showPI:)];
[button setTitle:#"This Button"];
self.navigationItem.rightBarButtonItem = button;
//[[self.navigationItem rightBarButtonItem] setWidth:50];
NSLog(#"Button width is %f.", self.navigationItem.rightBarButtonItem.width);
[button release];
}
[self.view setNeedsDisplay];
You're right. That line isn't needed. As far as the rest of the code goes I don't see what's wrong with it. The only thing I've come up with so far is that self isn't the currently displayed view controller or that you're missing a navigation controller. Perhaps you've created your UINavigationBar yourself instead of using a navigation controller?
Anyway, for easier debugging I would suggest the following:
- (void)showRightBarButton:(id)sender
{
NSLog(#"Showing button");
UIBarButtonItem *button = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(showPI:)];
self.navigationItem.rightBarButtonItem = button;
[button release];
}
EDIT: The width isn't interesting. It's always 0.0 unless you specify it yourself.
The problem is that you're adding the button in the wrong place. You're not supposed to add the button to the navigation item of the navigation controller, but to the navigation item of the controller that is currently displayed by the navigation controller.
You say you're using an NSNotification to trigger the addition of the bar button item. Where are you registering for the notification? Is it possible that the notification is being received before your view is loaded?
If you're registering for notifications in -init you may want to set a flag on your view controller that you should be displaying the bar button item and then reference that flag in -viewDidLoad to optionally display it.
Or you could just register for the notification in -viewDidLoad.