In UIActionSheet i have a uitableview and cancel button. By default cancel button appears at the top. I want to make it appear at the bottom after tableview. How do i do that?
it is work for me:
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"SomeTitle" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil, nil];
[actionSheet addButtonWithTitle:#"Some Action"];
[actionSheet addButtonWithTitle:#"Cancel"];
actionSheet.cancelButtonIndex = actionSheet.numberOfButtons -1;
I tried this and Cancel button is at the bottom:
menu = [[UIActionSheet alloc] initWithTitle:#"Actionsheet"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"destructive"
otherButtonTitles:#"other1", nil];
menu.actionSheetStyle = UIActionSheetStyleDefault;
[menu addButtonWithTitle:#"Cancel"];
By default Cancel button is hidden, adding a Cancel will shows it.
BUT: if you have additional gui elements on your actionsheet you have to
option1) position those to hide other buttons (to have space for your gui element). Its a tweak, but can work in some situation OR
option2) you have to manually add your button to the actionsheet
Actionsheet's built-in buttons are not align-able to the bottom freely because the purpose is different for this built-in gui elements.
See this: Adding UIPickerView to UIActionSheet (buttons at the bottom)
Example in Swift:
func presentMyActionSheetIOS7() {
let actionSheet: UIActionSheet = UIActionSheet(title: "What do you want to do?", delegate: self, cancelButtonTitle: nil, destructiveButtonTitle: nil)
actionSheet.addButtonWithTitle("Change Transparency")
actionSheet.addButtonWithTitle("Hide Photo")
actionSheet.addButtonWithTitle("Cancel")
actionSheet.cancelButtonIndex = actionSheet.numberOfButtons - 1
actionSheet.showInView(self.view)
}
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
switch buttonIndex {
case 0:
println("Change Transparency")
case 1:
println("Hide Photo")
case 2:
println("Cancel")
default:
println("Default")
}
}
Related
I have a method which throws up an actionSheet which is populated by an array.
The problem is that as soon as I place that method in the sender for 1 button, it fires off for every single button press.
I only want it to display for the one button (btnPortfolio).
Here is the code for my buttons:
- (IBAction)btnPortfolio:(id)sender {
[self populatePortfolioList];
}
- (IBAction)btnAdd:(id)sender {
}
- (IBAction)btnRefresh:(id)sender {
}
and here is my method:
-(void)populatePortfolioList{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Choose your option"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (NSString *title in portfolio_list) {
[actionSheet addButtonWithTitle:title];
}
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:#"Cancel"];
[actionSheet showInView:self.view];
}
since you are using IBActions, I assume that you have somehow created the methods by ctrl+dragging from the buttons into your code? is that the case? it might be possible that you accidentally connected more than one of your buttons with the method btnPortfolio which causes populatePortfolioList to be called any time the button is pressed
Hi I am facing very different kind of problem. I am using actionsheet in my iPhone application. So when I use predefine values of otherButtonTitles and if I try to change the text size then it works fine. But when I add buttons dynamically then it's not working properly.
My code looks like this:
- (void)showActions
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:cancelTitle
destructiveButtonTitle:nil
otherButtonTitles:notifications, about, faq, settings, logout, nil];
[actionSheet showInView:self.view];
}
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet {
for (UIView *_currentView in actionSheet.subviews) {
if ([_currentView isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)_currentView;
button.titleLabel.font = [UIFont systemFontOfSize:FONT_SIZE_16];
}
}
}
So above thing working fine. But if I try following things its not working
-(void) showCategories
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
// categoryData is string array....
for (NSString *category in categoryData) {
[actionSheet addButtonWithTitle:category];
}
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:#"Cancel"];
[actionSheet showInView:self.view];
}
And I tried to change text size like above then its not working. Is there any reason? Need help. Thank you.
When total number of buttons exceeds height to display without
scrolling this problem occurs. (If anyone else finds the way then
please post an answer. But i think there's no answer to this !!)
On 4 inch device (640x1136 resolution), number of max buttons displayed are 11
On 3.5 inch device (640x960 resolution), number of max buttons displayed are 8.
A piece of advice:: I think if you use actionsheet this way to display more than 10 elements, Apple could reject your app. Use UIPickerView for this kind of behaviour.
It could be probably a bug on iOS7. But the last button is not separated from the previous one
As you can see from the image. This happens on both Simulator and device using iOS7 GM.
Does everyone else has the same problem?
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:#"Title"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:#"First", #"Second", #"Third", #"Fourth", nil];
[actionSheet showInView:self.view];
As you can see the code is quite simple.
Any idea on how to fix the problem? Or some third party library I can use instead of UIActionSheet ?
I think ActionSheet requires a cancel button.So you can add the cancel button title.
Another way is: Specify actionSheet's cancelButtonIndex.
For example,in your case, you can add a "Cancel" in otherButtonTitles at index 4 and then specifiy
actionSheet.cancelButtonIndex = 4.
I found a way to make it work on iPhone and iPad in the least hacky way:
Only init the UIActionSheet with a title
Add your buttons
Add a "CANCEL" button at last
set the CancelButtonIndex to that last index
I assume that the missing separator is caused by the cancel button not being recognized as a separate case when adding it first or through the init.
I found that adding a cancel button with an empty string after initialization works. The cancel button won't show up and the separator shows up.
[sheet addButtonWithTitle: #""];
[sheet setCancelButtonIndex: sheet.numberOfButtons - 1];
But this only works for iPad. On iPhone, an empty cancel button shows up, but I found a hacky workaround to make it work. In addition to the above, in willPresentActionSheet add this code in:
NSInteger offset = 55;
CGRect superFrame = actionSheet.superview.frame;
superFrame.origin.y += offset;
[actionSheet.superview setFrame: superFrame];
// hide underlay that gets shifted with the superview
[(UIView*)[[actionSheet.superview subviews] objectAtIndex: 0] removeFromSuperview];
// create new underlay
CGRect underlayFrame = CGRectMake(0, -offset, superFrame.size.width, superFrame.size.height);
UIView* underlay = [[UIView alloc] initWithFrame: underlayFrame];
underlay.alpha = 0.0f;
[underlay setBackgroundColor: [UIColor colorWithWhite: 0.0f alpha: 0.4f]];
[actionSheet.superview insertSubview: underlay atIndex: 0];
// simulate fade in
[UIView animateWithDuration: 0.3f animations:^{
underlay.alpha = 1.0f;
}];
This shifts down the sheet to hide the cancel button off the screen
The simplest fix is to pass #"" to the cancel button title instead of nil during allocation.
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:#"Title"
delegate:self
cancelButtonTitle:#"" // change is here
destructiveButtonTitle:nil
otherButtonTitles:#"First", #"Second", #"Third", #"Fourth", nil];
[actionSheet showInView:self.view];
UIActionSheet *asAccounts = [[UIActionSheet alloc]
initWithTitle:Localized(#"select_an_account")
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles: nil];
for (int i=0; i<[result count]; i++) {
ACAccount *acct = [result objectAtIndex:i];
[asAccounts addButtonWithTitle:[acct username]];
asAccounts.tag = i;
}
[asAccounts addButtonWithTitle:Localized(#"Cancel")];
asAccounts.cancelButtonIndex = result.count;
[asAccounts showInView:self.view];
If you have a cancel button, the last row will be shown. That is the temp fix I am using now. Do not know any solution if you do not want a cancel button to show
It seems that the initWithTitle:delegate:cancelButtonTitle:destructiveButtonTitle:otherButtonTitles: method is buggy and you shouldn't specify any cancel button here at all. Btw, it seems that a destructive button set in that method also won't work very well.
Instead of it you should:
provide a custom cancel button as the last button in the buttons array, eg: ["Action 1", "Action 2", "Close"] or sheet.addButtonWithTitle("Close")
manually set the cancel button index, e.g. sheet.cancelButtonIndex = 2
Then everything will work as expected. On the iPad the button will be automatically hidden and on the iPhone it will be styled and placed in the proper way.
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet {
if ([UIDevice currentDevice].systemVersion.floatValue < 8.0f) {
UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(8, 88, actionSheet.frame.size.width - 16, 0.5)];
separator.backgroundColor = [UIColor colorWithRed:219.0f/255 green:219.0f/255 blue:223.0f/255 alpha:1];
[actionSheet addSubview:separator];
}
}
Every button has height 44. My actionSheet doesn't have title. And I wanted to add separator between second and third buttons. That's why I use number 88.
So I'm completely drawing a blank on the name of the class that draws one of these modal prompts with multiple options. I've attached a screenshot. It's the prompt that's confirming whether or not the user wants to sign out.
That's a UIActionSheet, Read UIActionSheet Class Reference.
Example
In your header, you need to add the <UIActionSheetDelegate> protocol. Then in your #implementation this is how you would call this specific sheet:
UIActionSheet * sampleSheet = [[UIActionSheet alloc] initWithTitle:#"Are you sure you'd like to sign out from Path?" delegate:self
cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Sign Out" otherButtonTitles:nil];
[sampleSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
[sampleSheet showInView:self.view];
And this is how you would handle the sheet:
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch ( buttonIndex )
{
case 0:
NSLog(#"User Chose Cancel");
break;
case 1:
NSLog(#"User Chose to Sign out.");
break;
}
}
You want UIActionSheet Class Reference
See UIActionSheet, I think that's the class you're looking for.
UIActionSheet *popupQuery;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
//give the user an option to choose an image from their library or take a new photo...
popupQuery = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Take Photo", #"Choose From Library", nil];
popupQuery.tag = 0;
}
else {
//give the user an option to choose an image from their library or take a new photo...
popupQuery = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Choose From Library", nil];
popupQuery.tag = 1;
}
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[popupQuery showInView:[self.view window]];
[popupQuery release];
I have an array of strings that I want to use for button titles on a UIActionSheet. Unfortunately, the otherButtonTitles: argument in the method invocation takes a variable length list of strings, not an array.
So how I can I pass these titles into the UIActionSheet? The workaround I've seen suggested is to pass nil into otherButtonTitles:, then specify the button titles individually by using addButtonWithTitle:. But this has the problem of moving the "Cancel" button to the first position on the UIActionSheet rather than the last; I want it to be the last one.
Is there a way to 1) pass an array in lieu of a variable list of strings, or alternatively 2) move the cancel button to the bottom of the UIActionSheet?
Thanks.
I got this to work (you just need to, be ok with a regular button, and just add it after :
NSArray *array = #[#"1st Button",#"2nd Button",#"3rd Button",#"4th Button"];
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Title Here"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
// ObjC Fast Enumeration
for (NSString *title in array) {
[actionSheet addButtonWithTitle:title];
}
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:#"Cancel"];
[actionSheet showInView:self.view];
One little note: [actionSheet addButtonWithTitle:] returns the index of that button, so to be safe and "clean" you can do this:
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:#"Cancel"];
Taking Jaba's and Nick's answers and extending them a little further. To incorporate a destruction button into this solution:
// Create action sheet
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
// Action Buttons
for (NSString *actionName in actionNames){
[actionSheet addButtonWithTitle: actionName];
}
// Destruction Button
if (destructiveName.length > 0){
[actionSheet setDestructiveButtonIndex:[actionSheet addButtonWithTitle: destructiveName]];
}
// Cancel Button
[actionSheet setCancelButtonIndex: [actionSheet addButtonWithTitle:#"Cancel"]];
// Present Action Sheet
[actionSheet showInView: self.view];
There is the swift version for the response :
//array with button titles
private var values = ["Value 1", "Value 2", "Value 3"]
//create action sheet
let actionSheet = UIActionSheet(title: nil, delegate: self, cancelButtonTitle: nil, destructiveButtonTitle: nil)
//for each value in array
for value in values{
//add a button
actionSheet.addButtonWithTitle(value as String)
}
//display action sheet
actionSheet.showInView(self.view)
To get value selected, add delegate to your ViewController :
class MyViewController: UIViewController, UIActionSheetDelegate
And implement the method "clickedButtonAtIndex"
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
let selectedValue : String = values[buttonIndex]
}