When was the last time you told your designer you couldn't customize UIAlertController? Now it is possible. Without using any private API.
DWAlertController is an UIAlertController that supports displaying any view controller instead of title and message. DWAlertController fully copies the look and feel of UIAlertController and has the same API.
This alert successfully used in production in our app Dash Wallet.
DWAlertController(see Advanced alert in the Example app)
DWAlertController is written in Objective-C and optimized for Swift. All API that
DWAlertController provides is the same as
let controller = ... // instantiate view controller let alert = DWAlertController(contentController: controller) let okAction = DWAlertAction(title: NSLocalizedString("OK", comment: ""), style: .cancel, handler: nil) alert.addAction(okAction) present(alert, animated: true)
UIViewController *controller = ...; // instantiate view controller DWAlertController *alert = [DWAlertController alertControllerWithContentController:controller]; DWAlertAction *okAction = [DWAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:DWAlertActionStyleCancel handler:nil]; [alert addAction:okAction]; [self presentViewController:alert animated:YES completion:nil];
DWAlertController works with a custom content controller, the view of the content controller must correctly implement Autolayout.
You might have used the same technique when implementing dynamic-sized
For more information see https://stackoverflow.com/a/18746930
Since DWAlertController maintain scrolling of large content controllers internally (as UIAlertController does) there is no need in placing the content of content view controller within UIScrollView.
backgroundColor of the content controller's view should be transparent (
UIAlertController.Style.alertis supported (since there are a lot of decent implementations of actionSheet-styled controls)
performTransition(toContentController:animated:)method, it may have a different height.
iOS 9 or later.
UIAlertController achieves such vibrant and expressive background color by using the private CoreAnimation class
CABackdropLayer which is lying within another private class
This layer uses a
"overlayBlendMode" to apply the effect to the view behind it. To get more information refer this answer.
As we wanted to use this alert in production we couldn't use any of those APIs. There are two possible options to get decent appearance comparable to using the private API.
CIOverlayBlendModeto it. This approach results in the closest appearance to
UIAlertController. However, there are several reasons why this approach cannot be used. Screenshotting during presentation adds a noticeable lag, neither it can't be done after presentation which might have led to blinking the content behind the alert. It would also have to take a screenshot when the user rotates the screen wich also lead to lags.
UIVisualEffectViewto do all work. As a dimming view, we use
pathproperty to dynamically modify the "hole" during rotation or keyboard animation. While this is NOT a 100% smooth solution, it works almost perfectly and looks very close to
All the colors and layout constants have been carefully copied from the
To run the example project, clone the repo, and run
pod install from the Example directory first.
DWAlertController is available through CocoaPods. To install it, simply add the following line to your Podfile:
Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
You can install Carthage with Homebrew using the following command:
$ brew update $ brew install carthage
To integrate DWAlertController into your Xcode project using Carthage, specify it in your
.package(url: "https://github.com/podkovyrin/DWAlertController.git", .upToNextMajor(from: "0.2.1")),
DWAlertControllerto your App targets dependencies like so:
.target(name: "App", dependencies: ["DWAlertController"]),
Andrew Podkovyrin, email@example.com
DWAlertController is available under the MIT license. See the LICENSE file for more info.