Ios13 Uialertcontroller with Custom View & Preferredstyle as Actionsheet Grayscale All Colors

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
Sample Image

iOS 9
Sample Image

iOS 10
Sample Image

UIAlertController does not turn all elements in the background to B/W

Thank you for your help.

In order to have a more flexible solution I decided to create a subclass of UIAlertController which captures a screenshot, turns it to grayscale colors and inserts it behind the UIAlertController when it gets presented. This way it works without having to do any additional work, and you don't need to implement fade animations for every single element that does not turn to grayscale colors by default.

Github repo: UIAlertControllerDimmed



Related Topics



Leave a reply



Submit