How to set action to the backButtonItem on the navigation bar? - iphone

How to set action to the backButtonItem on the navigation bar? I have a navigation bar, when I'm pressing the back button, I need to alert some message to the user, and only after user's reaction - return to the previous view. How can I do it? Thanx!
- (void)viewDidLoad
{
[super viewDidLoad];
//no one field don't changed yet
isDirty = FALSE;
//edited user
//set default values
newData = [data copy];
//setting navigation controller rigth button
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Save"
style:UIBarButtonSystemItemDone
target: self
action: #selector(saveBtnUserClick)];
self.navigationItem.rightBarButtonItem = rightButton;
[rightButton release];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonSystemItemDone
target: self
action: #selector(backBtnUserClick)];
self.navigationItem.backBarButtonItem = leftButton;
[leftButton release];
}
//and my method for reaction
-(IBAction) backBtnUserClick
{
NSLog(#"\n Back pressed");
//back to previous view
[self.navigationController popViewControllerAnimated: TRUE];
}

Add the < UINavigationControllerDelegate > in the header file and use this in the .m
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
//insert your back button handling logic here
// let the pop happen
return YES;
}

This sounds like a job for UIAlertView. Instead of calling popViewControllerAnimated: in your IBAction methods, alloc/init a UIAlertView and present it. Then, when the user taps a button on the UIAlertView, dismiss the UIAlertView and call popViewControllerAnimated:.
- (IBAction)backBtnUserClicked:(id)object {
UIAlertView *av = [[[UIAlertView alloc] initWithMessage:#"Wait!"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil] autorelease];
[av show];
}
In your UIAlertViewDelegate methods call popViewControllerAnimated:.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
[[self navigationController] popViewControllerAnimated:YES];
}
To set the action on the back button:
[[[self navigationController] leftBarButtonItem] setTarget:self];
[[[self navigationController] leftBarButtonItem] setAction:#selector(backBtnUserClicked:)];

Related

UITextView is not resigning when added as sub view of UIAlertView

I've added UITextView as a sub view of UIAlertView, I've added UIToolBar with a Done button (using UIBarButtonItem) as inputAccessoryView to allow user to resign keyboard`. It's just working fine in iOS6.0. And not in iOS5.0.
I've break point and checked in all the way I can, for reconfirming my self, I've made a sample project and checked the same in both the iOS versions, and the problem is same.
Here's the code, that's messing with me,
-(UIToolbar *)accessoryView
{
if (!accessoryView) {
accessoryView = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0)];
UIBarButtonItem *btn = [[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(hideKeyBoard)];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
accessoryView.items = [NSArray arrayWithObjects:flexibleSpace,btn, nil];
[accessoryView setTintColor:[[UIColor blackColor]colorWithAlphaComponent:0.5]];
}
return accessoryView;
}
-(IBAction) showAlertWithTextView: (id) sender
{
UIAlertView *alert = [[UIAlertView alloc] initWithFrame:CGRectMake(0, 50, 320, 200)];
alert.title = nil;
alert.message = nil;
alert.delegate = self;
//textview I've added in .h file
textView = [[UITextView alloc] initWithFrame:alert.bounds];
textView.text = #"This is a UITextView";
textView.keyboardAppearance = UIKeyboardAppearanceAlert;
textView.editable = YES;
textView.inputAccessoryView = [self accessoryView];
[alert addSubview:textView];
[alert show];
}
- (void)hideKeyBoard {
[textview resignFirstResponder];
//[self.view endEditing:YES]; //this is also not worked
}
Here's list of steps I'm doing,
Showing Alert with Textview
Focus to Textview
Tap on Done button to resign TextView
Its not resigning in iOS5 but resigning in iOS6
Any idea? What's going wrong?
Actually your textview is not the first responder. The first responder is your alertView.
So you should try this....
[textField resignFirstResponder];
[alertView resignFirstResponder];
To use this code you must declare your alertView object in your.h file
I've solved it, as solution given by #iOS Developer, but as I've so many UIAlertView objects to handle, I've added a property of UIAlertView in delegate, and assigning it with the object of my alertview like this,
-(void)willPresentAlertView:(UIAlertView *)alertView
{
//set current alertview
[[AppDelegate sharedDelegate] setCurrentAlertView:alertView];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//will remove current alertview reference
[[AppDelegate sharedDelegate] setNilCurrentAlertView];
}
- (void)hideKeyBoard {
[textView resignFirstResponder];
//when need to resign UITextView, get current alertview object
UIAlertView *alertView = [[AppDelegate sharedDelegate] getCurrentAlertView];
if(alertView) {
[alertView resignFirstResponder];
}
}
In AppDelegate.m file,
#pragma mark - UIAlertView Resign
- (void) setCurrentAlertView:(UIAlertView *)alert{
self.alertObj = alert;
}
- (void) setNilCurrentAlertView {
self.alertObj = nil;
}
- (UIAlertView *)getCurrentAlertView {
return (UIAlertView *)self.alertObj;
}
As it is somewhat late but I am wondering that your code will not work in iOS7 or not as from iOS7 onwards UIAlertView is not allowing to add any subview (As you are adding UITextView as subview of UIAlertView).
If your requirement is not to compulsory using the UITextView then you can use UIAlertView with following configuration with default textfield in alert.
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Title"
message:#"Message"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
[message setAlertViewStyle:UIAlertViewStylePlainTextInput];
[message show];
And you can get value of this textfield in delegate of UIAlertView like this,
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
[alertView textFieldAtIndex:0].text;
}

How to refresh UITableViewController in iphone/iPad

-(void)reloadView{
NSLog(#"IN RELOAD VIEW ");
[[self tableView] reloadData];
}
- (void)viewDidLoad {
UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
[self navigationItem].rightBarButtonItem = barButton;
[activityIndicator startAnimating];
[self callStudentsWebService];
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
[self setTitle:#"Students"];
self.navigationController.toolbarHidden = NO;
self.navigationController.toolbar.barStyle = UIBarStyleBlack;
UIBarButtonItem *add = [[UIBarButtonItem alloc] initWithTitle:#"Add Student" style:UIBarButtonItemStyleBordered target:self action:#selector(addStudent)];
UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *import = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemOrganize target:self action:#selector(addStudent)];
NSArray* toolbarItems = [NSArray arrayWithObjects:add,flexible,import, nil];
self.toolbarItems = toolbarItems;
}
Above is my Code in a Class which is a subclass of UITableViewController.
Now my problem is when I come onto the screen First Time it get the records from web service from the method [self callStudentsWebService] . Now i have a button in uitoolbar in the same view which updates the list . I am calling the reloadView method to refresh the List but it calls the numberOfRowsInSection and viewDidLoad method but does not call cellForRowAtIndexPath method. But when i goto other screen and come back again it does refresh my List from start.
What could be the reason ?? Please help i am new in iPad Development. And i m doing all this in iPad.
Thanks alot
EDITED
#interface StudentsList : UITableViewController {
DetailViewController *detailViewController;
UIToolbar *toolbar;
UIActivityIndicatorView *activityIndicator;
}
May be your data.count is 0? If there is some data it should call cellForRowAtIndexPath after [[self tableView] reloadData];
Do the refresh code in another separate method -(void)refreshData then call this whenever you want such as in -viewDidLoad or on a button tap...
Try to call -(void)reloadView from
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self reloadView];
}

Set Textfield Data on click save button in iphone

I have a modalviewcontroller and have two buttons on it: Cancel and Save. There is a UITextField which is editable.
Whenever I click on save button I do save it but the text doesnot get save because when I click on the button to open the modalviewcontroller, the text disappears. Dont know whats wrong with my code.
Here is my code :
- (void)viewWillAppear:(BOOL)animated {
self.cancel = self.navigationItem.leftBarButtonItem;
self.save = self.navigationItem.rightBarButtonItem;
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStylePlain target:self action:#selector(cancelAction)];
self.navigationItem.leftBarButtonItem = cancelButton;
[cancelButton release];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStylePlain target:self action:#selector(saveAction)];
self.navigationItem.rightBarButtonItem = saveButton;
[saveButton release];
[super viewWillAppear:animated];
}
-(IBAction) cancelAction{
[[self parentViewController] dismissModalViewControllerAnimated:YES];
}
-(IBAction) saveAction{
NSString *text = [textFieldBeingEdited text];
[textFieldBeingEdited setText:text];
[self setDescription:text];
[[self parentViewController] dismissModalViewControllerAnimated:YES];
}
I am not sure if I have to use the following code to save the text in textfield :
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self dismissModalViewControllerAnimated:YES];
}
I don't see in your code anywhere that you are setting the text in the UITextField when the view appears. You can add some code to your viewWillAppear method to set the text when the view appears, such as:
[textField setText:[self description]];
(It looks like you are storing the NSString in the description variable.)
Also, if this is some kind of string that could be considered a User Default, you can store the string there. I've used this before and it populates my UITextField nicely.
Code Example:
-(void)viewDidLoad
{
stringValue = [[NSUserDefaults standardUserDefaults] stringForKey:#"string"];
[textField setText:stringValue];
}
-(IBAction)saveAction
{
stringValue = [textField text];
[[NSUserDefaults standardUserDefaults] setObject:stringValue forKey:#"string"];
}

UIBarButtonItem on specific views using UITabBarController

I have a UITabBarController and want a button seen only on one of the tabs, not the rest. So in my method to handle when tab bar is pressed, I add the button like this:
#pragma mark - UITabBarController delegate
- (void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
// check for what type of class you are based on the tab pressed
...
NSMutableArray *barItems = [[self.MainToolbar items] mutableCopy];
UIBarButtonItem *sortBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Sort" style:UIBarButtonItemStyleBordered target:self action:#selector(SortButtonPressed:)];
[barItems insertObject:sortBarButtonItem atIndex:0];
[self.MainToolbar setItems:barItems];
Now how do I remove it when in the other views when the tabBarController is pressed without disturbing their buttons in the UIToolBar they already have that were added in IB.
This is simply achieved the same way you added the button, simply make it an ivar, which gets instanciated only once when you detect the particular view controller the first time.
// in .h
UIBarButtonItem *extraButton;
// in .m
-(void)tabBarController:(UITabBarController *)tabBarController
didSelectViewController:(UIViewController *)viewController {
// if it is the view controller you want {
NSMutableArray *barItems = [[self.MainToolbar items] mutableCopy];
if(!extraButton) {
extraButton = [[UIBarButtonItem alloc]
initWithTitle:#"Sort"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(SortButtonPressed:)];
}
[barItems insertObject:sortBarButtonItem atIndex:0];
[self.MainToolbar setItems:barItems];
// else
// just remove the button
NSMutableArray *barItems = [[self.MainToolbar items] mutableCopy];
[barItems removeObjectAtIndex:0];
[self.MainToolbar setItems:barItems];
}
Don't forget to release the button later when you don't need it anymore, and it should ok.

UIBarButtonItem call UIActionsheet

in main view a have an navigationController on click on a row a call the detailview and add a button
seminareListinView.m
#import "SeminareListingView.h"
#import "Seminar.h"
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//gehe zurück zum ersten View
//NSLog(#"Received Data in seminareArray");
Seminar *dvController = [[Seminar alloc] initWithNibName:#"Seminar" bundle:nil];
NSString *selectedSeminarURL = [seminarURLArray objectAtIndex:indexPath.row];
//NSString *selectedNextXMLFile = [kategorienNextXMLFileArray objectAtIndex:indexPath.row];
dvController.seminarURLFromXML = selectedSeminarURL;
//dvController.XMLFile = selectedNextXMLFile;
[self.navigationController pushViewController:dvController animated:YES];
//Zeige den PDF Download Button
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"PDF Download" style:UIBarButtonItemStylePlain target:self action:#selector(showMenu)];
//anotherButton.action = #selector(showMenu);
dvController.navigationItem.rightBarButtonItem = anotherButton;
[anotherButton release];
[dvController release];
dvController = nil;
//[[self navigationController] popViewControllerAnimated:YES];
}
in the seminar view a have this method
seminar.m
- (void) showMenu
{
UIActionSheet *myMenu = [[UIActionSheet alloc]
initWithTitle: #"Überschrift"
delegate:self
cancelButtonTitle:#"Abbrechen"
destructiveButtonTitle:#"Etwas unwiderrufliches"
otherButtonTitles:#"Eins", #"Zwei", nil];
[myMenu showInView:self.view];
}
but i get an error by clicking on Button
2011-07-07 12:57:31.009 Seminar App2[4352:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SeminareListingView showMenu]: unrecognized selector sent to instance 0x6305f90'
*** Call stack at first throw:
In
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"PDF Download" style:UIBarButtonItemStylePlain target:self action:#selector(showMenu)];
Cange to:
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"PDF Download" style:UIBarButtonItemStylePlain target:dvController action:#selector(showMenu)];
It looks like you're implementing the showMenu method in the Seminar class, but you're telling the bar button to call it on the SeminareListingView object. If that's the case, then you need to set the bar button's delegate to an instance of the Seminar class.
you are doing it wrong. Put your barButton ite code into viewDidLoad of Seminar. You are adding target self which denotes to current view of stack while you actually want to assign target to Seminar Controller. So please cut the code(Adding BarButtonItem) from cellForRowMethod to viewDidLoad of Seminar Controller.