CalZone CalZone - 4 months ago 905
Swift Question

UIAlertController - add custom views to actionsheet

I'm trying to make the actionsheet as it shows in the messages app on iOS when we try to attach an image as in the screenshot.

I realized in new UIAlertController, we can't fit any custom views. Any way I can make exactly this?

My code looks pretty standard.

let alertController = UIAlertController(title: "My AlertController", message: "tryna show some images here man", preferredStyle: UIAlertControllerStyle.ActionSheet)

let okAction = UIAlertAction(title: "oks", style: .Default) { (action: UIAlertAction) -> Void in
alertController.dismissViewControllerAnimated(true, completion: nil)
let cancelAction = UIAlertAction(title: "Screw it!", style: .Cancel) { (action: UIAlertAction) -> Void in
alertController.dismissViewControllerAnimated(true, completion: nil)


self.presentViewController(alertController, animated: true, completion: nil)

enter image description here


UIAlertController extends UIViewController, which has a view property. You can add subviews to that view to your heart's desire. The only trouble is sizing the alert controller properly. You could do something like this, but this could easily break the next time Apple adjusts the design of UIAlertController.


var alertController = UIAlertController(title: "\n\n\n\n\n\n", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)

let margin:CGFloat = 8.0
let rect = CGRectMake(margin, margin, alertController.view.bounds.size.width - margin * 4.0, 100.0)
var customView = UIView(frame: rect)

customView.backgroundColor = UIColor.greenColor()

let somethingAction = UIAlertAction(title: "Something", style: UIAlertActionStyle.Default, handler: {(alert: UIAlertAction!) in println("something")})

let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: {(alert: UIAlertAction!) in println("cancel")})


self.presentViewController(alertController, animated: true, completion:{})


  UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"\n\n\n\n\n\n" message:nil preferredStyle:UIAlertControllerStyleActionSheet];

  CGFloat margin = 8.0F;
  UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(margin, margin, alertController.view.bounds.size.width - margin * 4.0F, 100.0F)];
  customView.backgroundColor = [UIColor greenColor];
  [alertController.view addSubview:customView];

  UIAlertAction *somethingAction = [UIAlertAction actionWithTitle:@"Something" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
  UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {}];
  [alertController addAction:somethingAction];
  [alertController addAction:cancelAction];
  [self presentViewController:alertController animated:YES completion:^{}];

That being said, a much less hacky approach would be to make your own view subclass that works similarly to UIAlertController's UIAlertActionStyle layout. In fact, the same code looks slightly different in iOS 8 and iOS 9.

iOS 8 enter image description here

iOS 9 enter image description here