Add UIPickerView & a Button in Action sheet - How?

后端 未结 11 1439
遥遥无期
遥遥无期 2020-11-22 15:40

My application requires following things to be added in an action sheet.

  • UIToolbar
  • Button on UIToolbar
  • UIPicker Control

I have

相关标签:
11条回答
  • 2020-11-22 16:10

    Marcio's excellent solution to this question was of great help to me in adding subviews of any kind to a UIActionSheet.

    For reasons that are not (yet) entirely clear to me, the bounds of the UIActionSheet can only be set after it has been displayed; both sagar's and marcio's solutions successfully address this with a setBounds:CGRectMake(...) message being sent to the actionsheet after it is shown.

    However, setting the UIActionSheet bounds after the sheet has been displayed creates a jumpy transition when the ActionSheet appeaars, where it "pops" into view, and then only scrolls in over the final 40 pixels or so.

    When sizing a UIPickerView after adding subviews, I recommend wrapping the setBounds message sent to the actionSheet inside an animation block. This will make the entrance of the actionSheet appear smoother.

    UIActionSheet *actionSheet = [[[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
    
    
    // add one or more subviews to the UIActionSheet
    // this could be a UIPickerView, or UISegmentedControl buttons, or any other 
    // UIView.  Here, let's just assume it's already set up and is called 
    // (UIView *)mySubView
    [actionSheet addSubview:myView];
    
    // show the actionSheet
    [actionSheet showInView:[UIApplication mainWindow]];
    
    
    // Size the actionSheet with smooth animation
        [UIView beginAnimations:nil context:nil];
        [actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
        [UIView commitAnimations]; 
    
    0 讨论(0)
  • 2020-11-22 16:12

    Since iOS 8, you can't, it doesn't work because Apple changed internal implementation of UIActionSheet. Please refer to Apple Documentation:

    Subclassing Notes

    UIActionSheet is not designed to be subclassed, nor should you add views to its hierarchy. If you need to present a sheet with more customization than provided by the UIActionSheet API, you can create your own and present it modally with presentViewController:animated:completion:.

    0 讨论(0)
  • 2020-11-22 16:15

    Even though this question is old, I'll quickly mention that I've thrown together an ActionSheetPicker class with a convenience function, so you can spawn an ActionSheet with a UIPickerView in one line. It's based on code from answers to this question.

    Edit: It now also supports the use of a DatePicker and DistancePicker.


    UPD:

    This version is deprecated: use ActionSheetPicker-3.0 instead.

    animation

    0 讨论(0)
  • 2020-11-22 16:15

    Yep ! I finally Find it.

    implement following code on your button click event, to pop up action sheet as given in the image of question.

    UIActionSheet *aac = [[UIActionSheet alloc] initWithTitle:@"How many?"
                                                 delegate:self
                                        cancelButtonTitle:nil
                                   destructiveButtonTitle:nil
                                        otherButtonTitles:nil];
    
    UIDatePicker *theDatePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0.0, 44.0, 0.0, 0.0)];
    if(IsDateSelected==YES)
    {
        theDatePicker.datePickerMode = UIDatePickerModeDate;
        theDatePicker.maximumDate=[NSDate date];
    }else {
        theDatePicker.datePickerMode = UIDatePickerModeTime;
    }
    
    self.dtpicker = theDatePicker;
    [theDatePicker release];
    [dtpicker addTarget:self action:@selector(dateChanged) forControlEvents:UIControlEventValueChanged];
    
    pickerDateToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
    pickerDateToolbar.barStyle = UIBarStyleBlackOpaque;
    [pickerDateToolbar sizeToFit];
    
    NSMutableArray *barItems = [[NSMutableArray alloc] init];
    
    UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
    [barItems addObject:flexSpace];
    
    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(DatePickerDoneClick)];
    [barItems addObject:doneBtn];
    
    [pickerDateToolbar setItems:barItems animated:YES];
    
    [aac addSubview:pickerDateToolbar];
    [aac addSubview:dtpicker];
    [aac showInView:self.view];
    [aac setBounds:CGRectMake(0,0,320, 464)];
    
    0 讨论(0)
  • 2020-11-22 16:20

    Update for iOS 7

    Apple docs for UIActionSheet: UIActionSheet is not designed to be subclassed, nor should you add views to its hierarchy

    I recommend against trying to customize the contents of an ActionSheet, as it can lead to serious invalid context errors in iOS 7. I just spent a few hours working through this problem and ultimately decided to take a different approach. I replaced the call to show the action sheet with a modal view controller containing a simple tableview.

    There are many ways to accomplish this. Here's one way that I just implemented in a current project. It's nice because I can reuse it between 5 or 6 different screens where I all users to select from a list of options.

    1. Create a new UITableViewController subclass, SimpleTableViewController.
    2. Create a UITableViewController in your storyboard (embedded in a navigation controller) and set its custom class to SimpleTableViewController.
    3. Give the navigation controller for SimpleTableViewController a Storyboard ID of "SimpleTableVC".
    4. In SimpleTableViewController.h, create an NSArray property that will represent the data in the table.
    5. Also in SimpleTableViewController.h, create a protocol SimpleTableViewControllerDelegate with a required method itemSelectedatRow:, and a weak property called delegate of type id<SimpleTableViewControllerDelegate>. This is how we will pass the selection back to the parent controller.
    6. In SimpleTableViewController.m, implement the tableview data source and delegate methods, calling itemSelectedatRow: in tableView:didSelectRowAtIndexPath:.

    This approach has the added benefit of being fairly reusable. To use, import the SimpleTableViewController class in your ViewController.h, conform to the SimpleTableViewDelegate, and implement the itemSelectedAtRow: method. Then, to open the modal just instantiate a new SimpleTableViewController, set the table data and delegate, and present it.

    UINavigationController *navigationController = (UINavigationController *)[self.storyboard instantiateViewControllerWithIdentifier:@"SimpleTableVC"];
    SimpleTableViewController *tableViewController = (SimpleTableViewController *)[[navigationController viewControllers] objectAtIndex:0];
    tableViewController.tableData = self.statesArray;
    tableViewController.navigationItem.title = @"States";
    tableViewController.delegate = self;
    [self presentViewController:navigationController animated:YES completion:nil];
    

    I create a simple example and posted it on github.

    Also see Showing actionsheet causes CGContext invalid context errors.

    0 讨论(0)
  • 2020-11-22 16:22

    To add to marcio's awesome solution, dismissActionSheet: can be implemented as follows.

    1. Add an ActionSheet object to your .h file, synthesize it and reference it in your .m file.
    2. Add this method to your code.

      - (void)dismissActionSheet:(id)sender{
        [_actionSheet dismissWithClickedButtonIndex:0 animated:YES];
        [_myButton setTitle:@"new title"]; //set to selected text if wanted
      }
      
    0 讨论(0)
提交回复
热议问题