How to customize UIActionSheet? iOS
Asked Answered
M

7

19

Is it possible to create an ActionSheet that have a label between two buttons like this image?

enter image description here

Mady answered 30/7, 2013 at 11:55 Comment(1)
I think you have to learn to understand the code an change it the way you want. Ask us on the way of learning it.Glasswork
A
28

EDIT 2018

I posted this code all the way back in iOS4 when it was potentially useful. iOS Development has grown staggeringly since then, please do not use this code unless you are writing an app for iOS4 for whatever reason! Please refer to the wonderful 3rd party library XLR Action Controller for your mondern actionsheet needs!

It is most certainly possible, and I like to do this all the time!

First, make a @property of an UIActionSheet (in this example, mine is called aac-- this comes in handy especially if you want to call it by UITextFields.

Next, in the method you bring up the actionsheet, say a -(IBAction)userPressedButton:(id)sender, create a local instance of the actionsheet.

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
                                                             delegate:self
                                                    cancelButtonTitle:nil
                                               destructiveButtonTitle:nil
                                                    otherButtonTitles:nil];

then add it to your property: self.aac = actionsheet

Now you basically have full reign to do anything in this ActionSheet, I will give you an abbreviated form of what I did for a recent project:

- (IBAction)sendDataButtonPressed:(id)sender {

    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
                                                             delegate:self
                                                    cancelButtonTitle:nil
                                               destructiveButtonTitle:nil
                                                    otherButtonTitles:nil];

    self.aac = actionSheet;

    UIImageView *background = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"actionsheet_bg.png"]];
    [background setFrame:CGRectMake(0, 0, 320, 320)];
    background.contentMode = UIViewContentModeScaleToFill;
    [self.aac addSubview:background];

    UIButton *cancelButton = [UIButton buttonWithType: UIButtonTypeCustom];
    cancelButton.frame = CGRectMake(0, 260, 320, 50);
    [cancelButton setBackgroundImage:[UIImage imageNamed:@"actionsheet_button.png"] forState: UIControlStateNormal];
    [cancelButton addTarget:self action:@selector(cancelButtonClicked:)    forControlEvents:UIControlEventTouchUpInside];
    cancelButton.adjustsImageWhenHighlighted = YES;
    [cancelButton setTitle:@"Cancel" forState:UIControlStateNormal];
    [cancelButton setTitleColor:[UIColor colorWithRed:0/255.0f green:177/255.0f blue:148/255.0f alpha:1.0f] forState:UIControlStateNormal];
    cancelButton.titleLabel.textAlignment = NSTextAlignmentCenter;
    cancelButton.titleLabel.font = [UIFont fontWithName: @"SourceSansPro-Light" size: 25];

    [self.aac addSubview: cancelButton];

    UIButton *emailResultsButton = [UIButton buttonWithType: UIButtonTypeCustom];
    emailResultsButton.frame = CGRectMake(25, 12, 232, 25);
    [emailResultsButton addTarget:self action:@selector(emailResultsTapped:) forControlEvents:UIControlEventTouchUpInside];
    emailResultsButton.adjustsImageWhenHighlighted = YES;
    [emailResultsButton setTitle:@"Email Results" forState:UIControlStateNormal];
    [emailResultsButton setTitleColor:[UIColor colorWithRed:255/255.0f green:255/255.0f blue:255/255.0f alpha:1.0f] forState:UIControlStateNormal];
    [emailResultsButton setTitleColor:[UIColor colorWithRed:0/255.0f green:177/255.0f blue:148/255.0f alpha:1.0f] forState:UIControlStateHighlighted];
    emailResultsButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    emailResultsButton.titleLabel.font = [UIFont fontWithName: @"SourceSansPro-Light" size: 20];
    [self.aac addSubview: emailResultsButton];

// lots of other buttons...

// then right at the end you call the showInView method of your actionsheet, and set its counds based at how tall you need the actionsheet to be, as follows:

[self.aac showInView:self.view];
[self.aac setBounds:CGRectMake(0,0,320, 600)];

Here is a picture of what happens (remember I omitted all the other buttons in the code example, but they are pictured here): enter image description here

Now, if you want to dismiss the actionSheet -- depending on how you set up your button structure, or perhaps use a UIToolBar (very common) -- you can then in the button's selector action, do this:

-(void)cancelButtonClicked:(id)sender { [self.aac dismissWithClickedButtonIndex:0 animated:YES]; }

Also, just FYI, getting all the dimensions just right for your layout will take a little time, as you aren't working with the view of your main UIView of your UIViewController, rather the view of the actionSheet, so it has different dimensions.

One trick I do is layout the actionsheet in Storyboard with a UIView, then place all the objects you want in your "actionsheet" in that UIView, and you should get accurate dimensions for all the images.

Let me know if you need clarification, good luck!

Adjust answered 30/7, 2013 at 14:11 Comment(8)
This code produces following error in IOS 7: CGContextSetFillColorWithColor: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.Anaximenes
I'm getting the same error as 1110, always seems to happen if you customise the actionsheet.Dorolisa
@Dorolisa to remove that error just set the title string to @"".Fen
@Dorolisa Great fix! However, just for everyone knowledge, I have noticed some graphic/drawing issues when laying out a background in the action sheet when I set the title. Just FYI.Adjust
What is the point of using an action sheet at this point? Why not just create a UIView an animate it?Mcclendon
@JamesParker I agree fully, this is some legacy code from all the way back in iOS 4. I agree with James that this should just be a UIView, I will update the answer.Adjust
It doesn't work. Nothing actually happens after using the codeJodhpurs
@Jodhpurs I apologize, this answer needs updating, it's very old code and still seem popular, i promise to do an updated guide on this, please refer to some of the other answers in this thread, the XLActionController is very good!Adjust
D
8

https://github.com/xmartlabs/XLActionController allows us to create any custom action sheet giving much more flexibility than the solutions proposed above.

These are some examples included in the github repository.

Disburse answered 21/12, 2015 at 14:33 Comment(1)
@WebberLai I'm almost sure it will not work since it uses swift specific features.Disburse
A
3

I was just going to add a small comment but i cant comment yet so ill post a full answer. If you want to avoid the IOS7 errors CGContextSetFillColorWithColor: invalid context 0x0. This is a serious error etc. You can use the following.

self.actionSheet = [[UIActionSheet alloc] initWithTitle:@""
                                               delegate:nil
                                      cancelButtonTitle:nil
                                 destructiveButtonTitle:nil
                                      otherButtonTitles:nil];

However that will mess up the graphic/drawing at the top of your action sheet as @Max said so if you dont already have a background your adding just add this code to give you the default action sheet look.

UIView *background = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
background.backgroundColor = [UIColor colorWithRed:204.0/255.0 green:204.0/255.0 blue:204.0/255.0 alpha:1];
[self.actionSheet addSubview:background];

then add whatever else you want to your custom action sheet.

Adah answered 6/1, 2014 at 22:20 Comment(0)
N
2

If you don't want to use any hacks on UIActionSheet to customize it you can check out a replacement for UIActionSheet that I made: https://github.com/JonasGessner/JGActionSheet It's completely customizable!

Neil answered 16/8, 2014 at 23:0 Comment(0)
C
1
UIButton* button = (UIButton*)sender;
    actionSheet = [[UIActionSheet alloc] initWithTitle:@"Share the PNR Status" delegate:self
                                     cancelButtonTitle:@"Cancel"
                                destructiveButtonTitle:nil
                                     otherButtonTitles:@"Send Message",@"Send Email",@"Facebook",nil];

    [[[actionSheet valueForKey:@"_buttons"] objectAtIndex:0] setImage:[UIImage imageNamed:@"chat.png"] forState:UIControlStateNormal];
    [[[actionSheet valueForKey:@"_buttons"] objectAtIndex:1] setImage:[UIImage imageNamed:@"email.png"] forState:UIControlStateNormal];
    [[[actionSheet valueForKey:@"_buttons"] objectAtIndex:2] setImage:[UIImage imageNamed:@"facebook_black.png"] forState:UIControlStateNormal];
 //*********** Cancel
    [[[actionSheet valueForKey:@"_buttons"] objectAtIndex:3] setImage:[UIImage imageNamed:@"cancel.png"] forState:UIControlStateNormal];
    [actionSheet showFromRect:button.frame inView:self.view animated:YES];
Cemetery answered 29/1, 2014 at 10:55 Comment(3)
This is using private API and will be rejected by Apple.Emissary
This running fine my app is on app store and apple approved it.Cemetery
Yes, but it is not supported and can result in broken code in the future if they update the implementationHaustellum
P
0

If you like Google style and want a lightweight library, you can have a look at this: https://github.com/ntnhon/MaterialActionSheetController

It's totally customizable.

enter image description here

Punchdrunk answered 23/8, 2016 at 10:20 Comment(0)
B
0

If you're still struggling with this, I have a library that may be of help. It lets you create custom action sheets. It has a bunch of built-in types and can be extended and restyled as well.

Bricebriceno answered 15/3, 2018 at 22:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.