UIAlertController – add custom views to actionsheet

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.

Swift 3

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

    let margin:CGFloat = 10.0
    let rect = CGRect(x: margin, y: margin, width: alertController.view.bounds.size.width - margin * 4.0, height: 120)
    let customView = UIView(frame: rect)

    customView.backgroundColor = .green
    alertController.view.addSubview(customView)

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

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

    alertController.addAction(somethingAction)
    alertController.addAction(cancelAction)

    DispatchQueue.main.async {
        self.present(alertController, animated: true, completion:{})
    }

Swift

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

let margin:CGFloat = 10.0
let rect = CGRect(x: margin, y: margin, width: alertController.view.bounds.size.width - margin * 4.0, height: 120)
let customView = UIView(frame: rect)

customView.backgroundColor = .green
alertController.view.addSubview(customView)

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

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

alertController.addAction(somethingAction)
alertController.addAction(cancelAction)

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

Objective-C

  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

iOS 10
enter image description here

Leave a Comment