I want to customise a UIActionSheet slightly; Just add a custom UIButton/UIImageView above the existing 2 buttons like in this previous post but with a custom button/image instead of text above the default buttons. I tried adding a simple UILabel to see if it works as in this post: UIActionSheet Customization.
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle: #""
delegate: self
cancelButtonTitle: NSLocalizedString(#"Cancel",#"cancel button")
destructiveButtonTitle: nil
otherButtonTitles: #"Send",nil];
actionSheet.tag = kCallActionSheetTag;
UILabel *btn = [[UILabel alloc] initWithFrame:
CGRectMake(18, 10, 140, 50)];
accountLabel.textAlignment = UITextAlignmentLeft;
accountLabel.textColor = [UIColor whiteColor];
accountLabel.text = #"Account";
accountLabel.font = [UIFont boldSystemFontOfSize:16];
accountLabel.backgroundColor = [UIColor clearColor];
[actionSheet addSubview:accountLabel];
[accountLabel release];
[actionSheet showInView:self.tabBarController.view];
[actionSheet setBounds:CGRectMake(0,0,320, 260)];
[actionSheet release];
If I use the code above, the two buttons are displaced vertically upwards and UILabel overlaps the top button. They seem to be locked to the top of the actionsheet. I would rather not add my own buttons and position them. What is the best way to do this?
Thanks
here is my suggestion,
My experience is from UIAlertView, I have not tested.
It is supposed to set top message huge to offset button y-offset.
then add your UILabel
Related
I m adding a UIView in UIActionSheet and I need to add four labels on the view and a close button.But I need the UIactionSheet to start from center of screen.When I m adhusting the dimensions I couldnot get it .
-(IBAction)buttontapped:(id)sender{
UIView *showDetailsView = [[UIView alloc]initWithFrame:CGRectMake(0,10, 320, 260)];
showDetailsView.backgroundColor = [UIColor whiteColor];
UILabel *name =[[UILabel alloc] init];
[name setFrame:CGRectMake(10, 40,250, 50)];
name.textAlignment = UITextAlignmentLeft;
name.backgroundColor = [UIColor clearColor];
name .font=[UIFont fontWithName:#"arial" size:12];
name.text=#"Name";
[showDetailsView addSubview:name];
UIActionSheet *aac = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:#"Close", nil];
aac.actionSheetStyle = UIActionSheetStyleAutomatic;
[aac addSubview:showDetailsView];
[aac setFrame:CGRectMake(0,0,320,400)];
[aac showInView:self.view];
}
I can see it added from the bottom but it is not expanding to the center of screen like in the following figure:I need to increase its height.
From one of the SO's answer I get this method and it's works like charm :)
-(void)setActionSheetHeight
{
CGRect actionSheetRect = self.myActionSheet.frame;
CGFloat orgHeight = actionSheetRect.size.height;
actionSheetRect.origin.y -= 214; //height of picker
actionSheetRect.size.height = orgHeight+214;
self.myActionSheet.frame = actionSheetRect;
[self.myPicker setShowsSelectionIndicator:YES];
CGRect pickerRect = self.myPicker.frame;
pickerRect.origin.y = orgHeight;
self.myPicker.frame = pickerRect;
}
Here myActionSheet is one UIActionSheet iVar.
Here myPicker is one UIPickerView iVar.
Instead of 214 static value you can set your desired value and according to that it will set the height of the UIActionSheet.
NOTE
Must be called after the action sheet is shown ie after the [self.myActionSheet showFromTabBar:self.tabBarController.tabBar]; kind of line of code. Means after call the show method on action sheet.
Use this:
[aac setBounds:CGRectMake(0,0,320,400)];
UIActionSheet is designed to be presented from the bottom of the screen.
You can display it in center on ipad only..not in iphone.
You can use custom Alertview for your requirement.
https://github.com/alokard/BlockAlertView
When you present the actionsheet, you need to send appropriate message to present it. Refer to
showFromRect:inView:animated:
showInView:
For showInView:, you can have an invisible view with the bottom at mid-height of the view controller and top aligned to the top of viewcontroller.
For showFromRect:inView:animated:, if you have any UIView to which the actionsheet needs to be anchored, you can used it there.
Hey so I have a problem where I am inserting an actionsheet into a view that is inside of a scrollview in a different view controller. The actionsheet works just fine, the problem is that if i go down at all in the scrollview the actionsheet gets clipped off. I've tried several solutions with no luck. I think the problem is that the actionsheet is being inserted into the view that is placed inside the scrollview. Anyone have any idea how to launch the action sheet from the view controller that the scrollview is in instead? Here is how I am trying to do it right now:
When a button is touched it calls this method:
- (IBAction)callDP:(id)sender {
UIButton *selectedButton = (UIButton *)sender;
actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
datePickerView = [[UIDatePicker alloc] initWithFrame:pickerFrame];
datePickerView.tag = 10;
[datePickerView addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:datePickerView];
[actionSheet setTitle:#"Start Date"];
UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Done"]];
closeButton.momentary = YES;
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
[closeButton addTarget:self action:#selector(dismissActionSheet) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:closeButton];
datePickerView.datePickerMode = UIDatePickerModeDate;
//THIS IS THE PART THAT I THINK I AM HAVING THE PROBLEM WITH
// [actionSheet showFromToolbar:self.toolbarItems];
//[actionSheet showFromTabBar:self.parentViewController.tabBarController.tabBar];
[actionSheet showInView:self.parentViewController.view];
}
Here is where I insert the view into the scrollview. I have it set up so that I am using a view from a different uiviewcontroller class to control everything. The reason I do that is so that i can have the scrollable part, but be able to visually create everything that I need without having to do it programmatically....I apologize if that is kind of confusing. I can clarify if needs be...but here it is. The viewcontroller class that contains the view I want to put into the scroll view is called registration page. Its inside of registrationPage that it calls the actionSheet. Let me know what you think...
registrationPage = [[RegistrationPageToInsertViewController alloc]init];
viewToInsert = registrationPage.view;
[scrollView addSubview:viewToInsert];
[scrollView setContentSize:viewToInsert.frame.size];
// [scrollView sendSubviewToBack:imgView];
//scrollView.contentSize=CGSizeMake(320,416);
[self.view bringSubviewToFront:scrollView];
Here are a couple of screenshots to help you see what I'm talking about:
instead of this line
[actionSheet showInView:self.parentViewController.view];
try like this.
[actionSheet showInView:self.view];
Just do as i say.You have a nib or viewController. Whatever. Just add a scrollView as subView to what you have.Then you just add all your textfields, labels and all will be subview of scrollView.this is the correct way to do that.if you present action sheet,you have to show that in self.View only.
I am trying to create a UIPickerView inside of a UIActionSheet with a "done" button in a bar on the action sheet above the picker and I am trying to display the action sheet from the tab bar.
here is the code I am using to create my picker:
_beepPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 320, 216)];
_beepPicker.showsSelectionIndicator = YES;
_beepPicker.dataSource = self;
_beepPicker.delegate = self;
here is the code I am using to create my action sheet (with my "done" button)
_beepPickerActionSheet = [[UIActionSheet alloc]
initWithTitle:nil
delegate:nil
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
UISegmentedControl *doneButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Done"]];
doneButton.momentary = YES;
doneButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
doneButton.segmentedControlStyle = UISegmentedControlStyleBar;
doneButton.tintColor = [UIColor blackColor];
[doneButton addTarget:self action:#selector(dismissBeepPicker:) forControlEvents:UIControlEventValueChanged];
[_beepPickerActionSheet addSubview:doneButton];
and here is how I'm adding my "done" button:
[_beepPickerActionSheet addSubview:_beepPicker];
and finally, here is how I am trying to display the action sheet:
[_beepPickerActionSheet showFromTabBar:self.tabBarController.tabBar];
The Action Sheet does display... but, I can only see about 30 pixels of the top of the Action sheet????????
Any idea what I may be doing incorrectly?
When I check my debugger... here is what I see for the frame of the Action Sheet
UIActionSheet: 0x6b304f0; frame = (0 455; 320 25);
Screenshot before:
Screenshot after:
Ok... I know what I was doing incorrect... I had to add
[_beepPickerActionSheet setBounds:CGRectMake(0,0,320,485)];
After I added it to the view.
I want to make the font size smaller for the text in the buttons of my action sheet as my text is longer than the width.
How can I make the font size smaller?
I'm guessing as you can add things like picker views to action sheets that I may need to add my own buttons to the action sheet, if so how ?
I need an example.
EDIT: I've made a little progress, but the actual button isn't shown, but you can see it working with the change in the button text when you click on it.
UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:#"Date Picker"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"OK",nil];
CGRect frame = CGRectMake(100.0, 80.0, 100.0, 40.0);
UIButton *pickerView = [[UIButton alloc] initWithFrame:frame];
[pickerView setTitle:#"FRED" forState:UIControlStateNormal];
[pickerView setTitle:#"Go Back" forState:UIControlStateNormal];
[pickerView setTitleColor:[UIColor blackColor] forState:UIControlEventTouchDown];
pickerView.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
pickerView.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
//[removeButton addTarget:self action:#selector(buttonEvent:) forControlEvents:UIControlEventTouchDown];
[pickerView setBackgroundColor:[UIColor blueColor]];
[menu addSubview:pickerView];
[menu showInView:self.view];
[pickerView release];
[menu release];
You may be able to do this directly, but note that actionsheet buttons are not standard UIButtons, but are their own special private control subclass. For this reason, when I need to customize an action sheet, I add my own custom subview to the UIActionSheet and then resize the sheet to match. The downside is that to match the look and feel I need a custom button image background. I adapted (but didn't check in a compiler) this example from Fitting a UIDatePicker into a UIActionSheet. Instead of the picker, just add your xib created UIView.
UIDatePicker *pickerView = [[UIDatePicker alloc] init];
pickerView.datePickerMode = UIDatePickerModeDate;
[myUIActionSheet addSubview:pickerView];
[myUIActionSheet showInView:self.view];
[myUIActionSheet setBounds:CGRectMake(0,0,320, myUIActionSheet.bounds.size.height + pickerView.bounds.size.height)];
CGRect pickerRect = pickerView.bounds;
pickerRect.origin.y = - pickerView.bounds.size.height; //you may need to change this offset
pickerView.bounds = pickerRect;
[pickerView release];
[myUIActionSheet release];
EDIT: To include a subview from a xib, add a UIView to the top level of the xib and wire it to a UIView property in your controller just as if it was a normal interface component. Within your controller, it will now be available.
You can also wire button actions normally instead of using the action sheet callback. You will need to close the action sheet after the press with something like [myUIActionSheet.dismissWithClickedButtonIndex:0 animated:YES]; I think that dismissing it as if it is modal will also work, IIRC.
Someone posted this code in another question to put a UIDatePicker in a UIAlertSheet:
UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:#"Date Picker"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:nil];
// Add the picker
UIDatePicker *pickerView = [[UIDatePicker alloc] init];
pickerView.datePickerMode = UIDatePickerModeDate;
[menu addSubview:pickerView];
[menu showInView:self.view];
[menu setBounds:CGRectMake(0,0,320, 500)];
CGRect pickerRect = pickerView.bounds;
pickerRect.origin.y = -100;
pickerView.bounds = pickerRect;
[pickerView release];
[menu release];
I have modified it to this:
UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:nil
delegate:nil
cancelButtonTitle:#"Done"
destructiveButtonTitle:nil
otherButtonTitles:nil];
// Add the picker
UIDatePicker *pickerView = [[UIDatePicker alloc] init];
pickerView.datePickerMode = UIDatePickerModeCountDownTimer;
[menu addSubview:pickerView];
[menu showInView:self.navigationController.tabBarController.view];
[menu setBounds:CGRectMake(0,0,320, 516)];
[pickerView setFrame:CGRectMake(0, 85, 320, 216)];
This yields an alert sheet correctly positioned (ignore the nil delegate; this is just for display purposes). The problem lies here:
(source: hosting-wizards.com)
As you can see, above the minute scroller, there is a layering problem. I have not confirmed if this occurs on the device. Any ideas as to why this is happening?
Another question: Why does the setBounds selector on the UIActionSheet have the Y-size set at such a high value for correct display? Setting the Y-size to 480 should create a full screen display, should it not? Setting this value to zero makes it nearly invisible.
SIDE NOTE: The code pasted above does not position the UIDatePicker in the same place that it is in the picture, but the layering problem occurs no matter where the UIDatePicker is placed. The layering issue is only on the top, not on the bottom.
You will avoid the display problem and get a much better looking result if you simply put the UIDatePicker in a new view and implement the slide-up-from-the-bottom behavior yourself. It's not that hard.
Create a UIView containing a date picker and a toolbar with a Done button on it. (In code or use Interface Builder, doesn't matter.)
Add the popup view as a subview of your main view.
Set the popup view's frame so that it is off the bottom of the screen: frame.origin.y = CGRectGetMaxY(mainView.bounds)
Call [UIView beginAnimations:nil context:nil]
Set the frame to where it should be: frame.origin.y -= CGRectGetHeight(popupView.bounds)
Call [UIView commitAnimations]
(Note that the frame setting stuff is pseudocode.)
That's it. Do it in reverse when you need to dismiss the view. I think it will be worth the trouble; sticking a date picker in a UIActionSheet looks incredibly tacky.
Using benzado's steps above, here's roughly what your code would look like if you use a UIView instead of an ActionSheet:
int height = 255;
//create new view
UIView * newView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, 320, height)];
newView.backgroundColor = [UIColor colorWithWhite:1 alpha:1];
//add toolbar
UIToolbar * toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, 320, 40)];
toolbar.barStyle = UIBarStyleBlack;
//add button
UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:nil];
toolbar.items = [NSArray arrayWithObjects:infoButtonItem, nil];
//add date picker
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
datePicker.hidden = NO;
datePicker.date = [NSDate date];
datePicker.frame = CGRectMake(0, 40, 320, 250);
[datePicker addTarget:self action:nil/*#selector(changeDateInLabel:)*/ forControlEvents:UIControlEventValueChanged];
[newView addSubview:datePicker];
//add popup view
[newView addSubview:toolbar];
[self.view addSubview:newView];
//animate it onto the screen
CGRect temp = newView.frame;
temp.origin.y = CGRectGetMaxY(self.view.bounds);
newView.frame = temp;
[UIView beginAnimations:nil context:nil];
temp.origin.y -= height;
newView.frame = temp;
[UIView commitAnimations];
I agree, it looks a lot better than using ActionSheets which are designed to display buttons, not pickers. You still need to add your own action handlers on the "Done" button and when the user changes the picker but this should get you started.
Do you really need to put your picker on the UIActionSheet? Why don't you use an inputView property from UIResponder class? It shows UIDatePicker (or any other view) automatically when your control (e.g. UITextField) becomes a first responder.
An example of using inputView with source code can be found here: Working with pickers.
try this
[menu sendSubviewToBack: pickerView];
and also move your picker 10 pixels down as you see in the screenshot it is not aliged to the bottom, might be
[pickerView setFrame:CGRectMake(0, 100, 320, 216)];
You might find this thread helpful for an alternative approach: http://discussions.apple.com/message.jspa?messageID=7923095