Button to Recognize Selected Path - iphone

Trying to have a button confirm the index selected in a tableview with a special class. This is how I would NSLog the result of the selected index.
- (void)selector:(IZValueSelectorView *)valueSelector didSelectRowAtIndex:(NSInteger)index {
NSLog(#"Selected index %d",index);
}
but I'm not sure how I'd confirm that with a button since the button uses an IBAction.
I want an alert to pop up once they click the button. This is what I have so far, but I get an error since it doesn't recognize what index means:
- (IBAction)submit:(id)sender {
UIAlertView *submit = [[UIAlertView alloc]
initWithTitle:#"Submit"
message:(#"Are you sure you want to submit %i", index)
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:nil];
[submit show];
}

If I understood your question correctly, you want to be able to select a row, and then press a button somewhere, to confirm that you selected it, and you don't know how to get the selected index, correct?
If you have an IBOutlet pointing to the tableView, you can get the selected index path, using:
self.myTableView.indexPathForSelectedRow
Or his cousin, indexPathsForSelectedRows for multiple selection
Also, be noted, that if you have a UIButton inside a cell, and you tap on the button, it doesn't mean that the cell will get selected. Selection occurs when the cell gets touched-up inside (aka. it gets blue coloured).
Of course, the cleanest and easiest method, would to avoid using a button entirely, and just using the UITableViewDelegate method:
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
// Do the UIAlertView thing here
}

Related

Getting the data of a particular row with a button infront of it and passing that data to the clickButton function

I am currently in the cellForRow method where I have a button infront of each row.
CellForRow:
JSONDecoder *decoder=[[JSONDecoder alloc] initWithParseOptions:JKParseOptionNone];
NSMutableArray *json=[decoder objectWithData:myData]; {This has a list of items in the dictionary format}
NSDictionary *dict=[json objectAtIndex:indexPath.row];
NSString *status=[dict valueForKey:#"status key in json"];
"dict" can be represented as:
{
status key in json="approved";
name="abc";
type="resourceName";
},
{
status key in json="rejected";
name="xyz";
type="bus";
},
{
status key in json ="pending";
name="pqr";
type="resource";
}...and so on .
Printing status will give me the status of all the rows.
approved
rejected
pending
But I only need the status of that particular row infront of which I am gonna click the button. This is because I need that status for each row separately to send it to the buttonPressed method when I click the button infront of that row. I don't want to do that in didSelectRow method.
How can I get the indexPath.row of a particular row(on clicking that row) so that I could write the method on click of the button corresponding to that particular row?
You just have to add the button as subview for your cell, and pass indexpath.row as a button tag.Thats it.
I have given the sample
//Create ur cell then do the following
UIButton *objBtn=[UIButton buttonWithType:UIButtonTypeCustom];
[objBtn setFrame:CGRectMake(100,5,50,50)];
[objBtn addTarget:self action:#selector(methodWhichGetsCallOnButtonClick:)forControlEvents:UIControlEventTouchUpInside];
objBtn.tag = indexPath.row;
[cell addSubview:objBtn];
Now in "methodWhichGetsCallOnButtonClick" method add your business logic.
Also take a look on this question.
EDIT:
Also See this link
Try this out, and revert me back if need any more help.
If I am not wrong you want indexPath of cell on button clicked.You can get the cell of that button(in button action) as follows:
UIButton *theButton = sender;
CreatedCell *cell = (CreatedCell *)[[theButton superview] superview];
After getting cell, you can get indexPath of that cell as follows:
theIndexPath = [[m_TableView indexPathForCell:cell] retain];
You can use tag to UIButton.
In cellForRowAtIndexPath Method
You set tag to Button like this
btn.tag=indexpath.row;
In Button Action method you can retrive tag value using this line
Action method for Button
-(void)btnAction:(id)sender
{
UIButton *btn=(UIButton *) sender;
int tagValue=btn.tag;
NSDictionary *dict=[json objectAtIndex:tagValue];
// From this dictionory you cann acces the stauts key value
}
I hope it works for you

How to disable a insert button for a Tableview Cell

I want to make a list so that users can add items to their favorites. I used uitableviewcelleditingstyleinsert for my tableview. When a user taps an insert button which has a + sign, the item will be added to the favorites list. However, I want each item in the favorites list to be unique, so I when a button is tapped, I want it to automatically become grayscale. How could I set this up in my app?
This is completely possible, but not the way you're going about it. You need to create your own accessoryView with the plus sign image, use - (void) accessoryButtonTapped: (UIControl *) button withEvent: (UIEvent *) event to know when it's been tapped and then change the UITableViewCell's accessory view based on the subsequent change to your data source.
//in your cell creation
UIImageView *i = nil;
if(cellAlreadyUsed)
i = [[UIImageView alloc] initWithImage:#"your_gray_image"];
else
i = [[UIImageView alloc] initWithImage:#"your_green_image"];
cell.accessoryView = i;
[i release];
- (void) accessoryButtonTapped: (UIControl *) button withEvent: (UIEvent *) event {
//handle changing your data source to reflect that cell was used and reload your table
}
If u want every item unique apply logic before inserting it to array.
Compare ur array items with the current item, if match with array item break the loop, u can show an alert also, if not add item to the array list.
It will be a tedious task to customize the insert button.

Activity Indicator IOS usage question

First I would like to thank everyone who attempts to help me with my problem, I am new to iOS development, specifically objective-c, so I apologize if my question is extremely obvious.
I am making an app that loads some new data (parsed from a website but it is NOT a UIWebView) into the same current view every time the user changes a selection on the picker view (UIPickerView). The method that inserts this new data into the current view is called -(IBAction) getNewData: (id) sender.
getNewData is called every time the user makes a new selection with the picker. This is how it is called within the picker method and the picker as well as everything else works fine.
- (void)pickerView:(UIPickerView*)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
NSString *choosen;
choosen = [currentLottoNames objectAtIndex:row];
[self getNewData:choosen];
}
I would like to implement an activity indicator (spinner) for the loading time in-between the time the user makes/changes his selection on the scroller to the time the actual data shows up in the view after the user has made his selection on the scroller. How would I go about implementing this?
Thank you.
To show the user that you are accessing information via apples built in status bar you use
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
If you would like to display like a pop up message you need to declare in the header a
UIAlertView *load_message;
and then when you would like to show the load_message use
load_message = [[UIAlertView alloc] initWithTitle:#"Loading..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
[load_message show];
UIActivityIndicatorView *active = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
active.center = CGPointMake(load_message.bounds.size.width / 2, load_message.bounds.size.height - 40);
[active startAnimating];
[load_message addSubview:active];
and that will show a pop up displayed to the user that you are loading something. This is for locking up the screen showing the user that you are getting some information.

UIActionSheet in Landscape has incorrect buttonIndicies

I have an action sheet that is causing me grief on the iphone in Landscape orientation. Everything displays just fine, but in Landscape, the first real button has the same index as the cancel button and so the logic doesn't work.
I've tried creating the actionSheet using initWithTitle: delegate: cancelButtonTitle: destructiveButtonTitle: otherButtonTitles: but that was just the same, my current code is as follows;
UIActionSheet* actionMenu = [[UIActionSheet alloc] init];
actionMenu.delegate = self;
actionMenu.title = folderentry.Name;
actionMenu.cancelButtonIndex = 0;
[actionMenu addButtonWithTitle:NSLocalizedString(#"str.menu.cancel",nil)];
[self addActiveButtons:actionMenu forEntry:folderentry];
[actionMenu showInView:[self.navigationController view]];
[actionMenu release];
The addActiveButtons method basically configures which buttons to add which it does using code like this;
[menu addButtonWithTitle:NSLocalizedString(#"str.menu.sendbyemail",nil)];
There are perhaps 6 buttons at times so in landscape mode the actionSheet gets displayed like this;
My delegate responds like this;
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"Cancel Button Index is : %d",actionSheet.cancelButtonIndex);
NSLog(#"Button clicked was for index : %d",buttonIndex);
NSString *command = [actionSheet buttonTitleAtIndex:buttonIndex];
DLog(#"COMMAND IS: %# for index: %d",command,buttonIndex);
if ([command isEqualToString:NSLocalizedString(#"str.menu.sendbyemail",nil)]) {
// Do stuff here
}
if ( ... similar blocks ... ) { }
}
In the example shown, I am finding that cancelButtonIndex is 0 as expected, but so is the button index for the first other button! This means if I click on the second (Save to Photos) button for example, my debug output looks like this;
Cancel Button Index is : 0
Button clicked was for index : 1
COMMAND IS: Send by Email for index: 1
I've tried various permutations and am now tearing my hair out wondering what I'm missing. I've had a good search around but the other problems people seem to be having are display issues, rather than functionality ones.
Can anyone see where I've gone wrong?
PS. I know this isn't the greatest UI experience, but I figure that most users will actually be in portrait most of the time or using the iPad version of the app so I'm prepared to accept the actionsheet default behaviour for landscape assuming I can get it to actually work!
OK, fixed it by counting how many buttons I was adding and then adding the cancel button as the last option, so my code looks like this;
int added = [self addActiveButtons:actionMenu forEntry:folderentry];
[actionMenu addButtonWithTitle:NSLocalizedString(#"str.menu.cancel",nil)];
actionMenu.cancelButtonIndex = added;
Hope that helps someone else struggling witht the same issue!
I ran into the same issue even though I already was including the Cancel Button as the last one in the action sheet and setting its index accordingly. My problems had to do with the 'Destructive' button. After some investigation, here is my take on the problem:
After N buttons have been added to the actionsheet, it switches it's layout to put the Destructive button at the top and the Cancel button at the button. In between is a scrollable view that includes all of the other buttons. Other sources indicate that this is a a table view.
For the iPhone, N is 7 for Portrait orientation and 5 for Landscape orientation. Those numbers are for all buttons including Cancel and Destructive.
It does not matter where in the action sheet you had originally put the Cancel and Destructive buttons within the action sheet. Once the limit has been reached, the Destructive button is moved to the top and the Cancel is moved to the bottom.
The problem is that the indices are not adjusted accordingly. So, if you did not initially add the Cancel as the last button and the Destructive as the first, the wrong index will be reported in actionSheet:clickedButtonAtIndex: as the initial report stated.
So, if you are going to have more than N buttons in your action sheet you MUST add the Destructive button to the actionSheet as the first button to the action sheet. You MUST add the Cancel button as the last button added to the action sheet. When initially constructing the sheet just leave both as nil, as described in another answer.
I had the same problem. To fix it, I just create an actionSheet with nil for all the buttons, and added buttons manually afterwards. Lastly, in the handler, ignore the firstOtherButtonIndex because it will be wrong (even if you set it ahead of time). Instead, assume that it is 1 because index 0 is the cancel button in this example. Here's the code:
NSArray *items = [NSArray arrayWithObjects:#"one", #"two", #"three", nil];
UIActionSheet* actionSheet = [[[UIActionSheet alloc] initWithTitle:#"Title" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil] autorelease];
[actionSheet addButtonWithTitle:#"Cancel"];
for (NSString *title in items) {
[actionSheet addButtonWithTitle:title];
}
[actionSheet addButtonWithTitle:#"Destroy"];
// set these if you like, but don't bother setting firstOtherButtonIndex.
actionSheet.cancelButtonIndex = 0;
actionSheet.destructiveButtonIndex = [items count]+1;
Also, don't forget to show this from a tab view if you're on an iPhone because the tab bar steals touch events and prevents the lower button from being hit.
My solution is to initialize like this specifying only the destructiveButtonTitle...
UIActionSheet * as =[[[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:#"Cancel"
otherButtonTitles:nil] autorelease];
[as addButtonWithTitle:#"Button 1"];
[as addButtonWithTitle:#"Button 2"];
That way you get the Cancel button at index 0 always and your own buttons begin at index 1 even when there is a scroll view.

disable Alert view button

I have an alert view for twitter posting.
Alert view has 2 button and a textfield
send and cancel
I want to disable send button, until user fills the message box(i.e textfield).
like,empty field kind of validation.
How can I disable send button?
I had a similar requirement and was able to do this without resorting to anything explicitly prohibited by Apple (ie, the use of private classes or API's). In the example below, I find and then disable the "Recover" button.
Note #1 -- The placement of "[alert Show]" is important. It (apparently) lays out the views, so must be done before attempting to look through the view hierarchy.
Note #2 -- the "contains:" method is one I defined that does an NSString case-insensitive substring search. Use rangeOfString perhaps in your code.
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Application Warning"
message:#"What should I do with the file?"
delegate:self
cancelButtonTitle:#"Ignore"
otherButtonTitles:#"Remove", #"Recover", nil];
[alert show];
// try to find and disable "Recover" button
for(UIView *aView in alert.subviews)
{
if ([[[aView class] description] contains:#"Button"])
{
UIButton *aButton = (UIButton *)aView;
if ([aButton.titleLabel.text contains:#"Recover"])
{
aButton.enabled = NO;
}
}
}
This is not possible with the current SDK. You will have to create a custom view to take the user's input. The fact you are adding a textfield to the UIAlertView is itself unsupported and could break in any future SDK anyway.
I would suggest you create a custom view and if you still want it to look like a UIAlertView you can do this with appropriate images and custom buttons.