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.
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
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.
Coco2d add UIalert,first time can show normal ,but next show will badly show two times,and when i add UITextField to cocos2d for input player information,when I leave this scene ,I 'm
sure UITextField have been release ,but in other scene this UITextField still on the screen
problem with UIAlert? I used it in many times in iOS game. Worked fine
UIAlertView* alert= [[[UIAlertView alloc] initWithTitle: #"Not Enough Coins!"
message: #"You need more Coins"
delegate: nil
cancelButtonTitle: #"Cancel"
otherButtonTitles:#"Ok", nil] autorelease];
[alert show];
For other UI elements, release it on leaving.
-(void)onExit
{
if(mytextBox)
{
[mytextBox removeFromSuperview];
}
[super onExit];
}
Is there a way to achieve this menu easily with the sdk or do I have to make it manually (combining an overlay view and other view with the buttons)?
Thanks in advance!
That's UIActionSheet class from standard UIKit framework
Easy example from Apple's documentation of UIActionSheet extended a bit by me to fire call action.
Delcare in the global scope of the ViewController:
UIActionSheet * actionSheet; and UIView * yourView;
Int the viewDidLoad:
actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Delete Note"
otherButtonTitles:#"Call",#"Add a Contact",nil];
[yourView = self.view]
To fire the menu by some declared button with IBAction you will need:
-(IBAction)viewMapButton:(id) sender
{
[actionSheet showInView:yourView];
}
To take appropriate action depending on user choice declare following method and check what [actionSheet buttonTitleAtIndex:buttonIndex] was equal to:
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString * what_action = [actionSheet buttonTitleAtIndex:buttonIndex];
NSLog(#"The %# button was tapped.", what_action);
if ([what_action isEqualToString:#"Call"])
{
NSString *phoneNumber = [[NSString alloc]
initWithString:#"telprompt:1234567890"];
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString:phoneNumber]];
}
}
[NOTE: Firing of call does not work on iOS Simulator]
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]
}