Adding a value to the predefined array for uitableview iphone - iphone

How can i add a new value to the predefined array for uitableview while clicking add button?
-(IBAction)addNewBreed:(id)sender
{
UIAlertView *addAlert=[[UIAlertView alloc]initWithTitle:#"Add New Item" message:#"\n\n" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Add",nil];
UITextField *addTextField=[[UITextField alloc]initWithFrame:CGRectMake(12,45,260,25)];
[addTextField becomeFirstResponder];
[addTextField setBackgroundColor:[UIColor whiteColor]];
addTextField.clearButtonMode=UITextFieldViewModeWhileEditing;
[addAlert addSubview:addTextField];
[addAlert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *buttonTitle=[alertView buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:#"Add"])
{
//HERE WHAT CODE SHOULD I ADD,MY ARRAY NAME 'ar'
}
else
return;
}

If your array is a NSMutableArray, then you can use following code:
[ar addObject: addTextField.text];//you may also enter any string here
[yourTableView reloadData];

Related

UITableView Edit Mode Add the cell defined by user?

I wanted to use the table editing mode so that the users can choose which Cells to add.
For eg I have
addArray = {#"Red",#"Blue",#"Green"};
Now , what I want is that when user enters the editing mode and presses the add button, he gets the options: Red,Blue,Green and selects the cell to be added.
-(IBAction)addButtonPressed
{
[displayArray addObject:"User's Choice"];
[self.tableview reloadData];
}
You probably want to use a UIActionSheet (see Apple docs):
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:#"Select an option"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Red", #"Green", #"Blue", nil];
[actionSheet showInView:self.view];
You will need to make your view controller conform to the UIActionSheetDelegate protocol:
#interface MyViewController : UITableViewController <UIActionSheetDelegate>
Then, implement the actionSheet:clickedButtonAtIndex: method in your view controller:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == actionSheet.firstOtherButtonIndex) {
// Red
[displayArray addObject:"Red"];
[self.tableview reloadData];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 1) {
// Green
[displayArray addObject:"Green"];
[self.tableview reloadData];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 2) {
// Blue
[displayArray addObject:"Blue"];
[self.tableview reloadData];
}
}

is there easy way to handle UIAlertView result without delegation?

I have a function that shows a UIAlertView with YES/NO buttons, and it is used only inside the function's scope so I dont want to implement a delegation to catch the user feedback.
Is there any way to know what button users clicked without implement UIAlertViewDelegate, something like:
[alert show];
if([alert indexOfClickedButton] == indexOfYes)
{
....
}
Or lambda expression as in Animation
There is no way to avoid delegation completely, but you could create a wrapper to that effect along these lines:
#interface MyAlertViewDelegate : NSObject<UIAlertViewDelegate>
typedef void (^AlertViewCompletionBlock)(NSInteger buttonIndex);
#property (strong,nonatomic) AlertViewCompletionBlock callback;
+ (void)showAlertView:(UIAlertView *)alertView withCallback:(AlertViewCompletionBlock)callback;
#end
#implementation MyAlertViewDelegate
#synthesize callback;
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
callback(buttonIndex);
}
+ (void)showAlertView:(UIAlertView *)alertView
withCallback:(AlertViewCompletionBlock)callback {
__block MyAlertViewDelegate *delegate = [[MyAlertViewDelegate alloc] init];
alertView.delegate = delegate;
delegate.callback = ^(NSInteger buttonIndex) {
callback(buttonIndex);
alertView.delegate = nil;
delegate = nil;
};
[alertView show];
}
#end
(ARC is assumed, if you are not using it change delegate = nil to [delegate release].)
Usage would be something like:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Confirm" message:#"Yes or No?" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Yes",#"No", nil];
[MyAlertViewDelegate showAlertView:alert withCallback:^(NSInteger buttonIndex) {
// code to take action depending on the value of buttonIndex
}];
I have written a blog post about how to (and why) add block callbacks to alert views, action sheets and animations:
http://blog.innovattic.com/uikitblocks/
If you just want a working implementation of this you can download the sources files from GitHub:
https://github.com/Innovattic/UIKit-Blocks
Usage:
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"My easy alert"
message:#"Would you like to perform some kind of action?"
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alert setHandler:^(UIAlertView* alert, NSInteger buttonIndex) {
NSLog(#"Perform some kind of action");
} forButtonAtIndex:[alert firstOtherButtonIndex]];
[alert show];
It's very easy. Say you have an alert, something like this:
//Alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Confirm" message:#"Yes or No?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Yes",#"No", nil];
[alert show];
You're going to need to add this method:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
A possible implementation of this method would look like this:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
//Checks For Approval
if (buttonIndex == 1) {
//do something because they selected button one, yes
} else {
//do nothing because they selected no
}
}
You can do this using custom view which can be hidden and shown to avoid ActionSheets
UIView *AlertVw=[UIView alloc]initWithFrame:CGRect(x,y,w,h)]];
UIButton *SaveButton=[UIButton alloc]initWithFrame:CGRect(x,y,w,h)]];
[CustomButton setTitle:#"Ok" forState:UIControlStateNormal];
[SaveButton addTarget:self action:#selector(SaveClicked) forControlEvents:UIControlEventTouchUpInside];
UIButton *CancelButton=[UIButton alloc]initWithFrame:CGRect(x,y,w,h)]];
[CustomButton setTitle:#"Cancel" forState:UIControlStateNormal];
[CancelButton addTarget:self action:#selector(CancelClicked) forControlEvents:UIControlEventTouchUpInside];
[AlertVw addSubview:SaveButton];
[AlertVw addSubview:CancelButton];
[self.view addSubview:AlertVw];
-(void)SaveButton
{
//Code to apply on Save clicked
[AlertVw removeFromSuperView]; //Also you can use AlertView.hidden=YES;
}
-(void)CancelButton
{
//Code to apply on cancel clicked
[AlertVw removeFromSuperView]; //Also you can use AlertView.hidden=YES;
}
No need to derive the class. With Block, it is easy to get user selected button index.
typedef void(^AlertViewCallBackBlock)(NSInteger selectedIndex);
#interface ABC ()
#property (nonatomic, copy) AlertViewCallBackBlock alertViewBlock;
#end
#implementation
- (void)showAlert {
self.alertViewBlock = ^(NSInteger selectedIndex) {
if (selectedIndex == 1) {
}
};
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Confirm" message:#"Yes or No?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Yes",#"No", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
self.alertViewBlock(buttonIndex);
}
#end
Thanks Arkku. Here is the Swift version.
https://github.com/exchangegroup/alert-view-with-callback-swift
let alertView = UIAlertView(...)
AlertViewWithCallback().show(alertView) { alertView, buttonIndex in
println("You closed alert by tapping button #\(buttonIndex)")
}
UIAlertView is deprecated from iOS 8.0, a better solution will be using UIAlertController:
let alert = UIAlertController(title: "message", message: "Title", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "YES", style: .Default, handler: { (action) -> Void in
// Action for YES
}))
alert.addAction(UIAlertAction(title: "NO", style: .Default, handler: { (action) -> Void in
// Action for NO
}))
self.view.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil)

Multiple UIActionSheets on the same delegate

I'm writing a puzzle game. When the user presses the check button, I see if the solution they entered is correct. Depending on the result, I present one of two action sheets for them. For now I just have some NSLog statements to make sure things are getting called, but only one of the sheets seems to work properly.
Nothing gets called when I click a button in showErrorsActionSheet. The action sheet disappears off the screen, but the logs never print.
I suspect it has something to do with having two actionsheets declared to the same delegate (self)
- (void) checkSolution {
//code determines the value of the BOOL allCorrect
if (allCorrect) { //IF ALL OF THE LETTERS WERE CORRECT
//display UIAlertView;
NSLog(#"allCorrect");
UIActionSheet *levelCompleteActionSheet = [[UIActionSheet alloc] initWithTitle:#"Congratulations! You Have Finished the Level!" delegate:self cancelButtonTitle:#"Review my work" destructiveButtonTitle:#"Choose next puzzle" otherButtonTitles:nil, nil];
[levelCompleteActionSheet showInView:self.view];
[levelCompleteActionSheet release];
}
else {
//[self showIncorrectLettersInRed];
UIActionSheet *showErrorsActionSheet = [[UIActionSheet alloc] initWithTitle:#"Sorry, thats not right. Show errors in red?" delegate:self cancelButtonTitle:#"No Thanks, I'll keep trying" destructiveButtonTitle:#"Yes please, I'm stuck!" otherButtonTitles:nil, nil];
[showErrorsActionSheet showInView:self.view];
[showErrorsActionSheet release];
}
}
the methods that are supposed to be called are:
- (void) levelCompleteActionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex != [actionSheet cancelButtonIndex]) {
NSLog(#"return to levelSelect");
//pushViewController:levelSelect
}
else {
NSLog(#"continue to examine solution");
}
}
- (void) showErrorsActionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex != [actionSheet cancelButtonIndex]) {
NSLog(#"show errors in red");
}
else {
NSLog(#"continue to try");
}
}
and Ive declared the UIActionSheet protocol in the interface file as follows:
#interface GamePlay : UIViewController <UIActionSheetDelegate> {
Set a tag for each actionSheet, then use a switch statement in the UIActionSheet delegate.
Assign a tag
- (void)checkSolution
{
if (allCorrect)
{
UIActionSheet *levelCompleteActionSheet = [[UIActionSheet alloc] initWithTitle:#"Congratulations! You Have Finished the Level!" delegate:self cancelButtonTitle:#"Review my work" destructiveButtonTitle:#"Choose next puzzle" otherButtonTitles:nil, nil];
[levelCompleteActionSheet setTag: 0];
[levelCompleteActionSheet showInView:self.view];
[levelCompleteActionSheet release];
}
else
{
UIActionSheet *showErrorsActionSheet = [[UIActionSheet alloc] initWithTitle:#"Sorry, thats not right. Show errors in red?" delegate:self cancelButtonTitle:#"No Thanks, I'll keep trying" destructiveButtonTitle:#"Yes please, I'm stuck!" otherButtonTitles:nil, nil];
[showErrorsActionSheet setTag: 1];
[showErrorsActionSheet showInView:self.view];
[showErrorsActionSheet release];
}
}
UIActionSheet Delegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch ( actionSheet.tag )
{
case 0: /* levelCompleteActionSheet */
{
switch ( buttonIndex )
{
case 0: /* 1st button*/
break;
case 1: /* 2nd button */
break;
}
}
break;
case 1: /* showErrorsActionSheet */
break;
}
}
The same would apply anywhere else in this class as well, including levelCompleteActionSheet: and showErrorsActionSheet:. The only difference is, you would need to create an iVar for each actionSheet instead of creating them in checkSolution.
The methods that will be called by a UIActionSheet on its delegate are the methods listed in the UIActionSheetDelegate protocol.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIModalViewDelegate_Protocol/UIActionSheetDelegate/UIActionSheetDelegate.html
To be called, your method must be one of those methods. I don't see levelCompleteActionSheet or showErrorsActionSheet listed in that protocol! :) Your method must be named actionSheet:clickedButtonAtIndex:, and not some name you make up out of whole cloth.
Using Tag solve this problem
levelCompleteActionSheet.tag = 100;
showErrorsActionSheet.tag = 101;
- (void) levelCompleteActionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
if(actionSheet.tag == 100){
// levelCompleteActionSheet implement your required function
}
else if(actionSheet.tag == 101){
// showErrorsActionSheet implement your required function
}
}

UITableView and the alertView: clickedButtonAtIndex method

I am playing around with xCode and was trying to create a small app that comprises of a table view (built using an array) comprising the names of various individuals. The user would be able to click on one of the rows in the table view and would be shown a UIAlert with an option to call the person or cancel.
If they click on cancel, the UIalert dismisses. If they click on the Call button, I want to launch the Phone application and dial their number.
Here's what I have in terms of code thus far:
//Generate the UIAlert when the user clicks on a row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexpath
{
NSUInteger row = [indexpath row];
NSString *rowValue = [listData objectAtIndex:row];
NSString *message = [[NSString alloc] initWithFormat:#"Contact %#", rowValue];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Call this Office"
message:message
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Call",nil];
[alert show];
[message release];
[alert release];
}
//Detect which of the UIAlert buttons was clicked and dial a different number
//based on the index of the original row that was selected
- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch (row)
{
case 1:
if (buttonIndex != [alert cancelButtonIndex])
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel://123456789"]];
}
break;
case 2:
if (buttonIndex != [alert cancelButtonIndex])
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel://987654321"]];
}
break;
default:
break;
}
}
Here's my question - I know that my switch statement above won't work - That method has no idea what "row" is. So, how exactly do I pass in/access the index of the row that the user tapped for use with my switch statement?
When you create the UIAlertView right before you say [alert show] set its tag
alert.tag = [indexPath row];
now in your switch(row) statement do
switch(alert.tag)

UIAlertView button tagging

Is there a way I can add a .tag to an UIAlertView button? Reason being, I'm adding a few dynamic buttons to the alert that will sometimes be in the alert and sometimes not. I figured the best way was to add a tag. Is there a better method for this?
The options that will ALWAYS be in the alert are Email, Save. And the 2 optional options are Tweet This and Facebook.
Thanks for any help in advance!
There is one method buttonTitleAtIndex for UIAlertView. Use that to find the button tapped by user.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *buttonString = [alertView buttonTitleAtIndex:buttonIndex];
if( [buttonString isEqualToString:#"Facebook"] ){
// your code here
} else if( [buttonString isEqualToString:#"twitter"] ){
// your code here
}
}
You can also use tag proprerty:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Info"
message:#"Info text"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
[alert setTag:0];
Then in delegate:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (alertView.tag) {
case 1: {
...
break;
}
...
default:
break;
}