I've added a button on cell of my table view like this-
UIButton* checkBoxBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[checkBoxBtn setBackgroundImage:[UIImage imageNamed:#"check_normal.png"] forState:UIControlStateNormal];
[checkBoxBtn addTarget:self action:#selector(checkBoxAction:) forControlEvents:UIControlEventTouchUpInside];
checkBoxBtn.tag = indexPath.row;
[cell.contentView addSubview:checkBoxBtn];
and this is my checkBoxAction
-(void) checkBoxAction: (UIButton *)sender
{
NSInteger i =sender.tag + 1;
float perc = (i*100/18.0);
NSLog(#"%.2f",perc);
NSString* percentageStr = [[NSString alloc] initWithFormat:#"%3.2f%%(%d out of 18)",perc, i];
barTitle.text = percentageStr;
barFGImage.hidden = NO;
if (perc == 100.00) {
[barFGImage setFrame:CGRectMake(barFGImage.frame.origin.x, barFGImage.frame.origin.y, 276.0, barFGImage.frame.size.height)];
}
else
[barFGImage setFrame:CGRectMake(barFGImage.frame.origin.x, barFGImage.frame.origin.y, 280*perc/100, barFGImage.frame.size.height)];
[sender setBackgroundImage:[UIImage imageNamed:#"check_select.png"] forState:UIControlStateNormal];
sender.userInteractionEnabled = NO;
}
And every thing OK for now, but i want to show an alert when user press checkBoxBtn and if user press OK then the checkBoxAction should called.I know we have UIAlertView delegate method
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
But problem is that how to get checkBoxBtn in it?
EDIT: It is OK with Midhun MP's answer, but i want one more thing- in my cell i have three labels and a button , with the click on check box i want to change label 'Due in 6 days' along with other stuff that we done in my checkBoxAction method
Please help me. Thanks.
For achieving this you need to implement the - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex delegate method.
You can do it like:
Declare a UIButton instance in .h
like:
UIButton *button;
Change the button adding method like:
UIButton* checkBoxBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[checkBoxBtn setBackgroundImage:[UIImage imageNamed:#"check_normal.png"] forState:UIControlStateNormal];
[checkBoxBtn addTarget:self action:#selector(showAlert:) forControlEvents:UIControlEventTouchUpInside];
checkBoxBtn.tag = indexPath.row;
[cell.contentView addSubview:checkBoxBtn];
- (void) showAlert:(id)sender
{
button = (UIButton *)sender
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: #"Cancel"];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 0)
{
[self checkBoxAction:button];
}
}
For getting the label:
Add a tag to the label in cellForRowAtIndexPath: like:
statusText.tag = 7;
[cell.contentView addSubview:statusText];
And you can get the label using the following code:
UILabel *tempLabel = (UIlabel *)[[button superview] viewWithTag:7];
tempLabel.text = #"Midhun";
Related
So I have an IBAction hooked up to multiple buttons in IB I want this action to be fired when another IBAction is called I also want it to recognise an int from the second action as the [sender tag].
// viewController.m
-(IBAction)buttonPress {
int getInter = [sender tag];
UIView *tmpView = [self.view viewWithTag:getInter];
NSString *title = [(UIButton *)sender currentTitle];
}
I then have another action that needs to call buttonPress.
-(IBAction)secondButtonPress {
int varInt = 1
[self buttonPress: nil] <--- How do I pass varInt that buttonPress would recognise as a sender Tag here?
}
I realise that I could just create the button like so and duplicate the code in secondButtonPress but that seems to messy...
UIButton *tmpButton2 = (UIButton *)[self.view viewWithTag:varInt];
So the question is, is there a way of tricking buttonPress into thinking it has been pressed and passing a variable through as the sender tag for that action. In a way programatically tricking buttonPress into thinking it has been pressed.
Thank you in advance.
I ended up hooking it up to the same IBAction and running an if statement to do something if that tag was called.
Seems simple now!
-(IBAction)buttonPress {
int getInter = [sender tag];
if ([sender tag] == 2) {
//Do something just for that button.
}
else
{
UIView *tmpView = [self.view viewWithTag:getInter];
NSString *title = [(UIButton *)sender currentTitle];
}
}
UIButton *btn1 = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, 20, 20)];
[btn1 setTitle:#"Button 1" forState:UIControlStateNormal];
btn1.tag = 1;
[btn1 addTarget:self action:#selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn1];
UIButton *btn2 = [[UIButton alloc] initWithFrame:CGRectMake(10, 50, 20, 20)];
[btn2 setTitle:#"Button 2" forState:UIControlStateNormal];
btn2.tag = 2;
[btn2 addTarget:self action:#selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn2];
UIButton *btn3 = [[UIButton alloc] initWithFrame:CGRectMake(10, 90, 20, 20)];
[btn3 setTitle:#"Button 3" forState:UIControlStateNormal];
btn3.tag = 3;
[btn3 addTarget:self action:#selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn3];
write button click method as following and get button tag in it..
-(IBAction)buttonClick:(id)sender {
UIButton *btn = (UIButton *) sender;
NSLog(#"%d",btn.tag);
}
Just set the tag in initWithNibName method. Follow the sample and see whether it is helpful for you!!
#property(nonatomic,strong)IBOutlet UIButton *btn1;
#property(nonatomic,strong)IBOutlet UIButton *btn2;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Set the Tag
self.btn1.tag=1;
self.btn1.tag=2;
}
return self;
}
-(IBAction)selectedButtonClick:(id)sender {
UIButton *btn = (UIButton *) sender;
NSLog(#"selectedButton%d",btn.tag);
}
I am trying to keep this UIAlertView up after the presses either of the buttons (1 & 2).
Once i click on the "+" button or the "-" button, I can see the UILabel text increment, then it closes the UIAlertView.
This is what i currently am using:
#pragma Alert View Methods
-(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
{
[self dismissWithClickedButtonIndex:buttonIndex animated:animated];
}
#pragma count functions
-(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1 || buttonIndex == 2) {
return;
}
else{
[self dismissWithClickedButtonIndex:buttonIndex animated:YES];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1) {
self.currentCountButtonCount++;
[self.countAlert setMessage:[NSString stringWithFormat:#"%d",self.countButtonCount + 1]];
}if (buttonIndex == 2) {
self.currentCountButtonCount--;
[self.countAlert setMessage:[NSString stringWithFormat:#"%d",self.countButtonCount - 1]];
}
}
- (IBAction)countClick:(id)sender {
// tallies and keeps current count number
if (!self.currentCountButtonCount)
self.currentCountButtonCount = 0;
NSString *alertMessage = [NSString stringWithFormat:#"%d", self.countButtonCount];
self.countAlert = [[UIAlertView alloc]initWithTitle:#"Count" message:alertMessage delegate:self cancelButtonTitle:#"end" otherButtonTitles:#"+",#"-", nil];
[self.countAlert show];
}
On my last question someone told me to do it custom and this is what im trying now and it still dismisses the UIAlert.
How can i keep it up while the label changes until they touch the end button?
What are you using is default button of AlertView and after click on that button it will automatically dismissed the alertview.
So you have to create your buttons programatically and add that buttons in your alertview like:
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
[btn setTitle:#"+" forState:UIControlStateNormal];
[countAlert addSubview:btn ];
on this btn call your method.
So you have to create two custom button with "+" and "-". and add that buttons in AlertView.
-(void)setAlertValue:(id)sender{
switch ([sender tag]) {
case 1:
{
// currentCountButtonCount++;
[self.countAlert setMessage:[NSString stringWithFormat:#"%d",++countButtonCount]];
}
break;
case 2:
{
//currentCountButtonCount--;
[self.countAlert setMessage:[NSString stringWithFormat:#"%d",--countButtonCount]];
}
break;
default:
break;
}
}
- (IBAction)countClick:(id)sender {
// tallies and keeps current count number
if (!currentCountButtonCount)
currentCountButtonCount = 0;
NSString *alertMessage = [NSString stringWithFormat:#"%d", countButtonCount];
self.countAlert = [[UIAlertView alloc]initWithTitle:#"Count" message:alertMessage delegate:self cancelButtonTitle:#"end" otherButtonTitles:nil, nil];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(10, 50, 40, 20)];
[btn addTarget:self action:#selector(setAlertValue:) forControlEvents:UIControlEventTouchUpInside];
[btn setBackgroundColor:[UIColor greenColor]];
btn.tag = 1;
[btn setTitle:#"+" forState:UIControlStateNormal];
UIButton *btn1 = [[UIButton alloc] initWithFrame:CGRectMake(230, 50, 40, 20)];
[btn1 addTarget:self action:#selector(setAlertValue:) forControlEvents:UIControlEventTouchUpInside];
[btn1 setBackgroundColor:[UIColor redColor]];
btn1.tag = 2;
[btn1 setTitle:#"-" forState:UIControlStateNormal];
[countAlert addSubview:btn];
[countAlert addSubview:btn1];
[self.countAlert show];
}
I don't want to rain in your parade, but if you think that an alert view is the best way to handle an increment/decrement of a variable, I would suggest you to reconsider your design.
UIAlertViews are meant for transient information and simplified decision making. A simple "Are you sure?" is the text-book example of an alert view usage.
From the user stand point, it's much more comforting being able to modify all the attributes in sliders or any other form of permanent input, and then, when sure, hit the confirm button with an alert view (or confirmation screen). Doing it in an Alert view is not only error prone, but counter-intuitive compared in the way that the rest of iOS works.
If you're having trouble on fitting another form of input in your application, please read on how to perform animations and reveal control as they are needed, hiding the input inside an UIAlertView is simply the easiest solution for you, but not the best for the user.
I have this code on my program
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *saveMessageBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[saveMessageBtn setImage:[UIImage imageNamed:#"btn_done.png"] forState:UIControlStateNormal];
[saveMessageBtn addTarget:self action:#selector(saveMessage) forControlEvents:UIControlEventTouchUpInside];
[saveMessageBtn setFrame:CGRectMake(0, 0, 49, 30)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:saveMessageBtn];
}
-(IBAction)saveMessage:(id)sender{
UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:nil delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send Now",#"Non Recurring",#"Recurring", nil];
[actionSheet showInView:self.view];
}
- (void)actionSheet:(UIActionSheet *) actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0){
NSLog(#"Send Now");
}
else if (buttonIndex == 1){
[self performSegueWithIdentifier:#"modalNonRecurring" sender:self];
}
else if (buttonIndex == 2){
[self performSegueWithIdentifier:#"modalRecurring" sender:self];
}
else{
NSLog(#"Cancel Clicked");
}
}
as you can see in the code, it supposed to perform a segue or do 'NSLog' when a particular button clicked.
But when I click a button, it does not perform what I want it to do, instead it displays this message in the debug area..
Presenting action sheet clipped by its superview. Some controls might not respond to touches. On iPhone try -[UIActionSheet showFromTabBar:] or -[UIActionSheet showFromToolbar:] instead of -[UIActionSheet showInView:].
By the way, I am using a UINavigationController that is inside a UITabBarController.
Anyone that has a great idea how to fix this? your help would be much appreciated. Thanks!
Add UIActionSheetDelegate delegate in .h file and try like this then it'l work.
UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:nil delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send Now",#"Non Recurring",#"Recurring", nil];
actionSheet.delegate = self;
[actionSheet showInView:self.view];
I have Custom Table View Cell In That I Have Two UIButton and One Text Field Named As edit and cancel and one textField. When I Click on edit at same time TextFeild Interaction is Enabled And Cancel Button Image Should Change. Its Working Fine For Me!!
But When I am Clicking On Edit Button Another Cells Cancel bitton Image id Changed Automatically! I know that this happening because I'm reusing the cell!! But I'm not able to find a solution...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
simpleTableIdentifier = #"MenuNameCell";
cell = (MenuNameCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (!cell) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MenuNameCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
NSLog(#"---------new cell agin");
}
else
{
for (UIView *view in [cell.contentView subviews])
[view removeFromSuperview];
NSLog(#"---------older use");
// _checkButton = (UIButton *)[cell.contentView viewWithTag:indexPath.row];
// _cancelButton = (UIButton *)[cell.contentView viewWithTag:indexPath.row];
}
// Creating Label Menu Name
_nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(8, 11, 82, 21)];
_nameLabel.backgroundColor = [UIColor clearColor];
_nameLabel.text = [_hotel._orderedMenus objectAtIndex:indexPath.row];
// Creating Label Menu Cost
_amountMenu = [[UILabel alloc] initWithFrame:CGRectMake(167, 13, 44, 21)];
_amountMenu.backgroundColor = [UIColor clearColor];
_amountMenu.text = [[_hotel._menuPrices objectAtIndex:indexPath.row] stringValue];
// Creating Text Field For Order Quantity
_textFieldQuantity = [[UITextField alloc] initWithFrame:CGRectMake(125,14,42,21)];
_textFieldQuantity.userInteractionEnabled = NO;
_textFieldQuantity.text = [[_hotel._selectedQuantity objectAtIndex:indexPath.row] stringValue];
// Creating Button For Check Order
_checkButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_checkButton setFrame:CGRectMake(232, 13, 25, 28)];
[_checkButton setBackgroundImage:[UIImage imageNamed:#"edit.png"]forState:UIControlStateNormal];
[_checkButton addTarget:self action:#selector(editQuantity:) forControlEvents:UIControlEventTouchUpInside];
[_checkButton setTag:indexPath.row];
// Creating Button For CANCEL Order
_cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_cancelButton setFrame:CGRectMake(265, 13, 25, 28)];
[_cancelButton setBackgroundImage:[UIImage imageNamed:#"cancel.png"] forState:UIControlStateNormal];
[_cancelButton addTarget:self action:#selector(cancelOreder:) forControlEvents:UIControlEventTouchUpInside];
[_cancelButton setTag:indexPath.row];
// Adding All To Call Content View
[cell.contentView addSubview:_nameLabel];
[cell.contentView addSubview:_amountMenu];
[cell.contentView addSubview:_textFieldQuantity];
[cell.contentView addSubview:_checkButton];
[cell.contentView addSubview:_cancelButton];
return cell;
}
Edit:
-(void)editQuantity:(id)sender
{
_textFieldQuantity.userInteractionEnabled = YES;
button = (UIButton *)sender;
row = button.tag;
NSLog(#"Check Button index is %d",row);
UIImage *buttonImage = [UIImage imageNamed:#"edit_over.png"];
[_checkButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
UIImage *buttonImageCancel = [UIImage imageNamed:#"check.png"];
[_cancelButton setBackgroundImage:buttonImageCancel forState:UIControlStateNormal];
_cancelButton.tag = 0;
}
-(void)cancelOreder:(id)sender{
button = (UIButton *)sender;
row = button.tag;
NSLog(#"The Row Selected iS At Cancel Order ISSSS----%d", row);
if (_cancelButton.tag == 0){
_textFieldQuantity.userInteractionEnabled = NO;
UIImage *buttonImageCancel = [UIImage imageNamed:#"check_over.png"];
[_cancelButton setBackgroundImage:buttonImageCancel forState:UIControlStateNormal];
UIImage *buttonImageCancel1 = [UIImage imageNamed:#"cancel.png"];
[_cancelButton setBackgroundImage:buttonImageCancel1 forState:UIControlStateNormal];
UIImage *buttonImage = [UIImage imageNamed:#"edit.png"];
[_checkButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
_cancelButton.tag = 1;
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"iHomeDelivery" message:#"Do You Want To Cancel the Order" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
Your problem is that _textFieldQuantity (and the others) is an instance variable. When editQuantity: and cancelOreder: are called the instance varialbe still has the same value that was set last time when adding a cell within cellForRowAtIndexPath: .
What could you do to fix it?
1st:
You could set the row in the tag of the button. Then, when the button is tapped on and the action is invoced get the tag and fetch the cell (you can call the table's cellForRowAtIndexPath method to get it. That is different from the delegate method that you implement) and then find the appropriate textField.
2nd:
A bit more work but probably smarter could be to implment a subclass of your table cell. Move the action methods to that very cell class. Doing so each button's action refers to an individual object wich is then the cell class and not the view controller. The cell class can have its own textField instance variables. It shoud even provide properties to the textField and other UIItems so that you can set their values in cellForRowAtIndexPath.
I would suggest the first solution as a quick starter. But for future use I strongly suggest to go the second way. That way will help you in similar situations in the future.
I have a view with a generic rounded rect button that segues to another view. When users press the rounded rect it starts a fetch. I would like to have a spinning wheel replace the text ("Next") inside the rounded rect button while the fetch is processed.
I created the spinner:
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
But I don't know how to make it replace the text in the rounded rect button.
Any suggestion? Thank you.
Create (or get a reference to) the button as usual, then, while handling the button click, create your spinner and set it as a subview of the button. It's probably also worth disabling the button to stop multiple clicks.
Something along the following lines should do the trick:
...
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(10, 10, 70, 40);
[button setTitle:#"Next" forState:UIControlStateNormal];
[button addTarget:self action:#selector(click:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
...
- (void)click:(UIButton *)button {
[button setTitle:#"" forState:UIControlStateNormal];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
spinner.frame = button.bounds;
[button addSubview:spinner];
button.enabled = NO;
// do your actual work...
}
I wrote a category that utilizes associated objects
UIButton+ActivityIndicator.h
// Created by reynaldo on 1/16/14.
#import <Foundation/Foundation.h>
#interface UIButton (ActivityIndicator)
- (void)startActivityIndicator;
- (void)stopActivityIndicator;
#end
UIButton+ActivityIndicator.m
// Created by reynaldo on 1/16/14.
#import <objc/runtime.h>
#import "UIButton+ActivityIndicator.h"
static char TITLE_KEY;
static char ACTIVITY_INDICATOR_KEY;
#implementation UIButton (ActivityIndicator)
- (void)startActivityIndicator {
objc_setAssociatedObject(self, &TITLE_KEY, self.currentTitle, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self setTitle:#"" forState:UIControlStateNormal];
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[self addSubview:activityIndicatorView];
activityIndicatorView.frame = CGRectMake(self.frame.size.width / 2, self.frame.size.height / 2. - 2, 7, 7);
[activityIndicatorView startAnimating];
objc_setAssociatedObject(self, &ACTIVITY_INDICATOR_KEY, activityIndicatorView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)stopActivityIndicator {
NSString *title = objc_getAssociatedObject(self, &TITLE_KEY);
UIActivityIndicatorView *activityIndicatorView = objc_getAssociatedObject(self, &ACTIVITY_INDICATOR_KEY);
if(activityIndicatorView) {
[activityIndicatorView removeFromSuperview];
}
if(title.length) {
[self setTitle:title forState:UIControlStateNormal];
}
}
#end