Repository files navigation

VersionLicensePlatformCarthage compatiblecodebeat badgeBuild Status MasterBuild Status Development

Introduction

Popup Dialog is a simple, customizable popup dialog written in Swift.

Features

  • Easy to use API with hardly any boilerplate code
  • Convenient default view with image, title, message
  • Supports custom view controllers
  • Slick transition animations
  • Fully themeable via appearance, including fonts, colors, corner radius, shadow, overlay color and blur, etc.
  • Can be dismissed via swipe and background tap
  • Objective-C compatible
  • Works on all screens and devices supporting iOS 8.0+

Installation

Cocoapods

PopupDialog is available through CocoaPods. For best results with Swift 3, I recommend installing CocoaPods version 1.1.0 (which might be a prerelease as of this release). Simply add the following to your Podfile:

use_frameworks!target'<Your Target Name>'pod'PopupDialog','~> 0.5'

Please note that this version is compatiable with iOS8

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. A minimum version of 0.17 is required.

To install, simply add the following lines to your Cartfile:

github"Orderella/PopupDialog" ~> 0.5

Manually

If you prefer not to use either of the above mentioned dependency managers, you can integrate PopupDialog into your project manually by adding the files contained in the Classes folder to your project.

Example

You can find this and more example projects in the repo. To run it, clone the repo, and run pod install from the Example directory first.

import PopupDialog
// Prepare the popup assets
lettitle="THIS IS THE DIALOG TITLE"letmessage="This is the message section of the popup dialog default view"letimage=UIImage(named:"pexels-photo-103290")
// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Create buttons
letbuttonOne=CancelButton(title:"CANCEL"){print("You canceled the car dialog.")}letbuttonTwo=DefaultButton(title:"ADMIRE CAR"){print("What a beauty!")}letbuttonThree=DefaultButton(title:"BUY CAR", height:60){print("Ah, maybe next time :)")}
// Add buttons to dialog
// Alternatively, you can use popup.addButton(buttonOne)
// to add a single button
popup.addButtons([buttonOne, buttonTwo, buttonThree])
// Present dialog
self.present(popup, animated:true, completion:nil)

Usage

PopupDialog is a subclass of UIViewController and as such can be added to your view controller modally. You can initialize it either with the handy default view or a custom view controller.

Default Dialog

publicconvenienceinit(
title:String?,
message:String?,
image:UIImage?=nil,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

The default dialog initializer is a convenient way of creating a popup with image, title and message (see image one and two).

Bascially, all parameters are optional, although this makes no sense at all. You want to at least add a message and a single button, otherwise the dialog can't be dismissed, unless you do it manually.

If you provide an image it will be pinned to the top/left/right of the dialog. The ratio of the image will be used to set the height of the image view, so no distortion will occur.

Custom View Controller

publicinit(
viewController:UIViewController,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

You can pass your own view controller to PopupDialog (see image three). It is accessible via the viewController property of PopupDialog, which has to be casted to your view controllers class to access its properties. Make sure the custom view defines all constraints needed, so you don't run into any autolayout issues.

Buttons are added below the controllers view, however, these buttons are optional. If you decide to not add any buttons, you have to take care of dismissing the dialog manually. Being a subclass of view controller, this can be easily done via dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?).

Transition Animations

You can set a transition animation style with .BounceUp being the default. The following transition styles are available

publicenumPopupDialogTransitionStyle:Int{case bounceUp
case bounceDown
case zoomIn
case fadeIn
}

Button Alignment

Buttons can be distributed either .Horizontal or .Vertical, with the latter being the default. Please note distributing buttons horizontally might not be a good idea if you have more than two buttons.

publicenumUILayoutConstraintAxis:Int{case horizontal
case vertical
}

Gesture Dismissal

Gesture dismissal allows your dialog being dismissed either by a background tap or by swiping the dialog down. By default, this is set to true. You can prevent this behavior by setting gestureDismissal to false in the initializer.

Completion

This completion handler is called when the dialog was dismissed. This is especially useful for catching a gesture dismissal.

Default Dialog Properties

If you are using the default dialog, you can change selected properties at runtime:

// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Present dialog
self.present(popup, animated:true, completion:nil)
// Get the default view controller and cast it
// Unfortunately, casting is necessary to support Objective-C
letvc= popup.viewController as!PopupDialogDefaultViewController
// Set dialog properties
vc.image =UIImage(...)
vc.titleText ="..."
vc.messageText ="..."
vc.buttonAlignment =.horizontal
vc.transitionStyle =.bounceUp

Styling PopupDialog

Appearance is the preferred way of customizing the style of PopupDialog. The idea of PopupDialog is to define a theme in a single place, without having to provide style settings with every single instantiation. This way, creating a PopupDialog requires only minimal code to be written and no "wrappers".

This makes even more sense, as popup dialogs and alerts are supposed to look consistent throughout the app, that is, maintain a single style.

Dialog Default View Appearance Settings

If you are using the default popup view, the following appearance settings are available:

vardialogAppearance=PopupDialogDefaultView.appearance()
dialogAppearance.backgroundColor =UIColor.white
dialogAppearance.titleFont =UIFont.boldSystemFont(ofSize:14)
dialogAppearance.titleColor =UIColor(white:0.4, alpha:1)
dialogAppearance.titleTextAlignment =.center
dialogAppearance.messageFont =UIFont.systemFont(ofSize:14)
dialogAppearance.messageColor =UIColor(white:0.6, alpha:1)
dialogAppearance.messageTextAlignment =.center
dialogAppearance.cornerRadius =4
dialogAppearance.shadowEnabled =true
dialogAppearance.shadowColor =UIColor.black

Overlay View Appearance Settings

This refers to the view that is used as an overlay above the underlying view controller but below the popup dialog view. If that makes sense ;)

letoverlayAppearance=PopupDialogOverlayView.appearance()
overlayAppearance.color =UIColor.black
overlayAppearance.blurRadius =20
overlayAppearance.blurEnabled =true
overlayAppearance.liveBlur =false
overlayAppearance.opacity =0.7

Note

Turning on liveBlur, that is realtime updates of the background view, results in a significantly higher CPU usage /power consumption and is therefore turned off by default now. Choose wisely whether you need this feature or not ;)

Button Appearance Settings

The standard button classes available are DefaultButton, CancelButton and DestructiveButton. All buttons feature the same appearance settings and can be styled seperately.

varbuttonAppearance=DefaultButton.appearance()
// Default button
buttonAppearance.titleFont =UIFont.systemFont(ofSize:14)
buttonAppearance.titleColor =UIColor(red:0.25, green:0.53, blue:0.91, alpha:1)
buttonAppearance.buttonColor =UIColor.clear
buttonAppearance.separatorColor =UIColor(white:0.9, alpha:1)
// Below, only the differences are highlighted
// Cancel button
CancelButton.appearance().titleColor =UIColor.lightGray
// Destructive button
DestructiveButton.appearance().titleColor =UIColor.red

Moreover, you can create a custom button by subclassing PopupDialogButton. The following example creates a solid blue button, featuring a bold white title font. Separators are invisble.

publicfinalclassSolidBlueButton:PopupDialogButton{overridepublicfunc setupView(){
defaultFont =UIFont.boldSystemFont(ofSize:16)
defaultTitleColor =UIColor.white
defaultButtonColor =UIColor.blue
defaultSeparatorColor =UIColor.clear
super.setupView()}}

These buttons can be customized with the appearance settings given above as well.

Dark mode example

The following is an example of a Dark Mode theme. You can find this in the Example project AppDelegate, just uncomment it to apply the custom appearance.

// Customize dialog appearance
letpv=PopupDialogDefaultView.appearance()
pv.titleFont =UIFont(name:"HelveticaNeue-Light", size:16)!
pv.titleColor =UIColor.white
pv.messageFont =UIFont(name:"HelveticaNeue", size:14)!
pv.messageColor =UIColor(white:0.8, alpha:1)
// Customize the container view appearance
letpcv=PopupDialogContainerView.appearance()
pcv.backgroundColor =UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00)
pcv.cornerRadius =2
pcv.shadowEnabled =true
pcv.shadowColor =UIColor.black
// Customize overlay appearance
letov=PopupDialogOverlayView.appearance()
ov.blurEnabled =true
ov.blurRadius =30
ov.liveBlur =true
ov.opacity =0.7
ov.color =UIColor.black
// Customize default button appearance
letdb=DefaultButton.appearance()
db.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
db.titleColor =UIColor.white
db.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
db.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)
// Customize cancel button appearance
letcb=CancelButton.appearance()
cb.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
cb.titleColor =UIColor(white:0.6, alpha:1)
cb.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
cb.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)

I can see that there is room for more customization options. I might add more of them over time.

Screen sizes and rotation

Rotation and all screen sizes are supported. However, the dialog will never exceed a width of 340 points. This way, the dialog won't be too big on devices like iPads. However, landscape mode will not work well if the height of the dialog exceeds the width of the screen.

Working with text fields

If you are using text fields in your custom view controller, popup dialog makes sure that the dialog is positioned above the keybord whenever it appears. You can opt out of this behaviour by setting keyboardShiftsView to false on a PopupDialog.

Testing

PopupDialog exposes a nice and handy method that lets you trigger a button tap programmatically:

publicfunc tapButtonWithIndex(index:Int)

Other than that, PopupDialog unit tests are included in the root folder.

Objective-C

PopupDialog can be used in Objective-C projects as well. Here is a basic example:

#import<PopupDialog/PopupDialog-Swift.h>
PopupDialog *popup = [[PopupDialog alloc] initWithTitle:@"TEST"message:@"This is a test message!"image:nilbuttonAlignment:UILayoutConstraintAxisHorizontal
transitionStyle:PopupDialogTransitionStyleBounceUp
gestureDismissal:YEScompletion:nil];
CancelButton *cancel = [[CancelButton alloc] initWithTitle:@"CANCEL"dismissOnTap:YESaction:^{
// Default action
}];
DefaultButton *ok = [[DefaultButton alloc] initWithTitle:@"OK"dismissOnTap:YESaction:^{
// Ok action
}];
[popup addButtons: @[cancel, ok]];
[selfpresentViewController:popup animated:YEScompletion:nil];

Requirements

Minimum requirement is iOS 8.0. This dialog was written with Swift 3, for 2.2 compatible versions please specify the X release.

Changelog

  • 0.5.4 Fixed bug where blur view would reveal hidden layer
    Improved view controller lifecycle handling
    Scroll views can now be used with gesture dismissal
  • 0.5.3 Fixed memory leak with custom view controllers
    Added UI automation & snapshot tests
  • 0.5.2 Fixed image scaling for default view
  • 0.5.1 Introduced custom button height parameter
    Reintroduced iOS8 compatibility
  • 0.5.0 Swift 3 compatibility / removed iOS8
  • 0.4.0 iOS 8 compatibility
  • 0.3.3 Fixes buttons being added multiple times
  • 0.3.2 Dialog repositioning when interacting with keyboard
    Non dismissable buttons option
    Additional completion handler when dialog is dismissed
  • 0.3.1 Fixed Carthage issues
  • 0.3.0 Objective-C compatibility
  • 0.2.2 Turned off liveBlur by default to increase performance
  • 0.2.1 Dismiss via background tap or swipe down transition
  • 0.2.0 You can now pass custom view controllers to the dialog. This introduces breaking changes.
  • 0.1.6 Defer button action until animation completes
  • 0.1.5 Exposed dialog properties
    (titleText, messageText, image, buttonAlignment, transitionStyle)
  • 0.1.4 Pick transition animation style
  • 0.1.3 Big screen support
    Exposed basic shadow appearance
  • 0.1.2 Exposed blur and overlay appearance
  • 0.1.1 Added themeing example
  • 0.1.0 Intitial version

Author

Martin Wildfeuer, mwfire@mwfire.de for Orderella Ltd., orderella.co.uk
You might also want to follow us on Twitter, @theMWFire | @Orderella

Thank you

Thanks to everyone who uses, enhances and improves this library, especially the contributors.

Images in the sample project

The sample project features two images from Markus Spiske raumrot.com:
Vintage Car One | Vintage Car Two
Thanks a lot for providing these :)

License

PopupDialog is available under the MIT license. See the LICENSE file for more info.

About

A simple, customizable popup dialog for iOS written in Swift. Replaces UIAlertController alert style.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

VersionLicensePlatformCarthage compatiblecodebeat badgeBuild Status MasterBuild Status Development

Introduction

Popup Dialog is a simple, customizable popup dialog written in Swift.

Features

  • Easy to use API with hardly any boilerplate code
  • Convenient default view with image, title, message
  • Supports custom view controllers
  • Slick transition animations
  • Fully themeable via appearance, including fonts, colors, corner radius, shadow, overlay color and blur, etc.
  • Can be dismissed via swipe and background tap
  • Objective-C compatible
  • Works on all screens and devices supporting iOS 8.0+

Installation

Cocoapods

PopupDialog is available through CocoaPods. For best results with Swift 3, I recommend installing CocoaPods version 1.1.0 (which might be a prerelease as of this release). Simply add the following to your Podfile:

use_frameworks!target'<Your Target Name>'pod'PopupDialog','~> 0.5'

Please note that this version is compatiable with iOS8

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. A minimum version of 0.17 is required.

To install, simply add the following lines to your Cartfile:

github"Orderella/PopupDialog" ~> 0.5

Manually

If you prefer not to use either of the above mentioned dependency managers, you can integrate PopupDialog into your project manually by adding the files contained in the Classes folder to your project.

Example

You can find this and more example projects in the repo. To run it, clone the repo, and run pod install from the Example directory first.

import PopupDialog
// Prepare the popup assets
lettitle="THIS IS THE DIALOG TITLE"letmessage="This is the message section of the popup dialog default view"letimage=UIImage(named:"pexels-photo-103290")
// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Create buttons
letbuttonOne=CancelButton(title:"CANCEL"){print("You canceled the car dialog.")}letbuttonTwo=DefaultButton(title:"ADMIRE CAR"){print("What a beauty!")}letbuttonThree=DefaultButton(title:"BUY CAR", height:60){print("Ah, maybe next time :)")}
// Add buttons to dialog
// Alternatively, you can use popup.addButton(buttonOne)
// to add a single button
popup.addButtons([buttonOne, buttonTwo, buttonThree])
// Present dialog
self.present(popup, animated:true, completion:nil)

Usage

PopupDialog is a subclass of UIViewController and as such can be added to your view controller modally. You can initialize it either with the handy default view or a custom view controller.

Default Dialog

publicconvenienceinit(
title:String?,
message:String?,
image:UIImage?=nil,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

The default dialog initializer is a convenient way of creating a popup with image, title and message (see image one and two).

Bascially, all parameters are optional, although this makes no sense at all. You want to at least add a message and a single button, otherwise the dialog can't be dismissed, unless you do it manually.

If you provide an image it will be pinned to the top/left/right of the dialog. The ratio of the image will be used to set the height of the image view, so no distortion will occur.

Custom View Controller

publicinit(
viewController:UIViewController,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

You can pass your own view controller to PopupDialog (see image three). It is accessible via the viewController property of PopupDialog, which has to be casted to your view controllers class to access its properties. Make sure the custom view defines all constraints needed, so you don't run into any autolayout issues.

Buttons are added below the controllers view, however, these buttons are optional. If you decide to not add any buttons, you have to take care of dismissing the dialog manually. Being a subclass of view controller, this can be easily done via dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?).

Transition Animations

You can set a transition animation style with .BounceUp being the default. The following transition styles are available

publicenumPopupDialogTransitionStyle:Int{case bounceUp
case bounceDown
case zoomIn
case fadeIn
}

Button Alignment

Buttons can be distributed either .Horizontal or .Vertical, with the latter being the default. Please note distributing buttons horizontally might not be a good idea if you have more than two buttons.

publicenumUILayoutConstraintAxis:Int{case horizontal
case vertical
}

Gesture Dismissal

Gesture dismissal allows your dialog being dismissed either by a background tap or by swiping the dialog down. By default, this is set to true. You can prevent this behavior by setting gestureDismissal to false in the initializer.

Completion

This completion handler is called when the dialog was dismissed. This is especially useful for catching a gesture dismissal.

Default Dialog Properties

If you are using the default dialog, you can change selected properties at runtime:

// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Present dialog
self.present(popup, animated:true, completion:nil)
// Get the default view controller and cast it
// Unfortunately, casting is necessary to support Objective-C
letvc= popup.viewController as!PopupDialogDefaultViewController
// Set dialog properties
vc.image =UIImage(...)
vc.titleText ="..."
vc.messageText ="..."
vc.buttonAlignment =.horizontal
vc.transitionStyle =.bounceUp

Styling PopupDialog

Appearance is the preferred way of customizing the style of PopupDialog. The idea of PopupDialog is to define a theme in a single place, without having to provide style settings with every single instantiation. This way, creating a PopupDialog requires only minimal code to be written and no "wrappers".

This makes even more sense, as popup dialogs and alerts are supposed to look consistent throughout the app, that is, maintain a single style.

Dialog Default View Appearance Settings

If you are using the default popup view, the following appearance settings are available:

vardialogAppearance=PopupDialogDefaultView.appearance()
dialogAppearance.backgroundColor =UIColor.white
dialogAppearance.titleFont =UIFont.boldSystemFont(ofSize:14)
dialogAppearance.titleColor =UIColor(white:0.4, alpha:1)
dialogAppearance.titleTextAlignment =.center
dialogAppearance.messageFont =UIFont.systemFont(ofSize:14)
dialogAppearance.messageColor =UIColor(white:0.6, alpha:1)
dialogAppearance.messageTextAlignment =.center
dialogAppearance.cornerRadius =4
dialogAppearance.shadowEnabled =true
dialogAppearance.shadowColor =UIColor.black

Overlay View Appearance Settings

This refers to the view that is used as an overlay above the underlying view controller but below the popup dialog view. If that makes sense ;)

letoverlayAppearance=PopupDialogOverlayView.appearance()
overlayAppearance.color =UIColor.black
overlayAppearance.blurRadius =20
overlayAppearance.blurEnabled =true
overlayAppearance.liveBlur =false
overlayAppearance.opacity =0.7

Note

Turning on liveBlur, that is realtime updates of the background view, results in a significantly higher CPU usage /power consumption and is therefore turned off by default now. Choose wisely whether you need this feature or not ;)

Button Appearance Settings

The standard button classes available are DefaultButton, CancelButton and DestructiveButton. All buttons feature the same appearance settings and can be styled seperately.

varbuttonAppearance=DefaultButton.appearance()
// Default button
buttonAppearance.titleFont =UIFont.systemFont(ofSize:14)
buttonAppearance.titleColor =UIColor(red:0.25, green:0.53, blue:0.91, alpha:1)
buttonAppearance.buttonColor =UIColor.clear
buttonAppearance.separatorColor =UIColor(white:0.9, alpha:1)
// Below, only the differences are highlighted
// Cancel button
CancelButton.appearance().titleColor =UIColor.lightGray
// Destructive button
DestructiveButton.appearance().titleColor =UIColor.red

Moreover, you can create a custom button by subclassing PopupDialogButton. The following example creates a solid blue button, featuring a bold white title font. Separators are invisble.

publicfinalclassSolidBlueButton:PopupDialogButton{overridepublicfunc setupView(){
defaultFont =UIFont.boldSystemFont(ofSize:16)
defaultTitleColor =UIColor.white
defaultButtonColor =UIColor.blue
defaultSeparatorColor =UIColor.clear
super.setupView()}}

These buttons can be customized with the appearance settings given above as well.

Dark mode example

The following is an example of a Dark Mode theme. You can find this in the Example project AppDelegate, just uncomment it to apply the custom appearance.

// Customize dialog appearance
letpv=PopupDialogDefaultView.appearance()
pv.titleFont =UIFont(name:"HelveticaNeue-Light", size:16)!
pv.titleColor =UIColor.white
pv.messageFont =UIFont(name:"HelveticaNeue", size:14)!
pv.messageColor =UIColor(white:0.8, alpha:1)
// Customize the container view appearance
letpcv=PopupDialogContainerView.appearance()
pcv.backgroundColor =UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00)
pcv.cornerRadius =2
pcv.shadowEnabled =true
pcv.shadowColor =UIColor.black
// Customize overlay appearance
letov=PopupDialogOverlayView.appearance()
ov.blurEnabled =true
ov.blurRadius =30
ov.liveBlur =true
ov.opacity =0.7
ov.color =UIColor.black
// Customize default button appearance
letdb=DefaultButton.appearance()
db.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
db.titleColor =UIColor.white
db.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
db.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)
// Customize cancel button appearance
letcb=CancelButton.appearance()
cb.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
cb.titleColor =UIColor(white:0.6, alpha:1)
cb.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
cb.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)

I can see that there is room for more customization options. I might add more of them over time.

Screen sizes and rotation

Rotation and all screen sizes are supported. However, the dialog will never exceed a width of 340 points. This way, the dialog won't be too big on devices like iPads. However, landscape mode will not work well if the height of the dialog exceeds the width of the screen.

Working with text fields

If you are using text fields in your custom view controller, popup dialog makes sure that the dialog is positioned above the keybord whenever it appears. You can opt out of this behaviour by setting keyboardShiftsView to false on a PopupDialog.

Testing

PopupDialog exposes a nice and handy method that lets you trigger a button tap programmatically:

publicfunc tapButtonWithIndex(index:Int)

Other than that, PopupDialog unit tests are included in the root folder.

Objective-C

PopupDialog can be used in Objective-C projects as well. Here is a basic example:

#import<PopupDialog/PopupDialog-Swift.h>
PopupDialog *popup = [[PopupDialog alloc] initWithTitle:@"TEST"message:@"This is a test message!"image:nilbuttonAlignment:UILayoutConstraintAxisHorizontal
transitionStyle:PopupDialogTransitionStyleBounceUp
gestureDismissal:YEScompletion:nil];
CancelButton *cancel = [[CancelButton alloc] initWithTitle:@"CANCEL"dismissOnTap:YESaction:^{
// Default action
}];
DefaultButton *ok = [[DefaultButton alloc] initWithTitle:@"OK"dismissOnTap:YESaction:^{
// Ok action
}];
[popup addButtons: @[cancel, ok]];
[selfpresentViewController:popup animated:YEScompletion:nil];

Requirements

Minimum requirement is iOS 8.0. This dialog was written with Swift 3, for 2.2 compatible versions please specify the X release.

Changelog

  • 0.5.4 Fixed bug where blur view would reveal hidden layer
    Improved view controller lifecycle handling
    Scroll views can now be used with gesture dismissal
  • 0.5.3 Fixed memory leak with custom view controllers
    Added UI automation & snapshot tests
  • 0.5.2 Fixed image scaling for default view
  • 0.5.1 Introduced custom button height parameter
    Reintroduced iOS8 compatibility
  • 0.5.0 Swift 3 compatibility / removed iOS8
  • 0.4.0 iOS 8 compatibility
  • 0.3.3 Fixes buttons being added multiple times
  • 0.3.2 Dialog repositioning when interacting with keyboard
    Non dismissable buttons option
    Additional completion handler when dialog is dismissed
  • 0.3.1 Fixed Carthage issues
  • 0.3.0 Objective-C compatibility
  • 0.2.2 Turned off liveBlur by default to increase performance
  • 0.2.1 Dismiss via background tap or swipe down transition
  • 0.2.0 You can now pass custom view controllers to the dialog. This introduces breaking changes.
  • 0.1.6 Defer button action until animation completes
  • 0.1.5 Exposed dialog properties
    (titleText, messageText, image, buttonAlignment, transitionStyle)
  • 0.1.4 Pick transition animation style
  • 0.1.3 Big screen support
    Exposed basic shadow appearance
  • 0.1.2 Exposed blur and overlay appearance
  • 0.1.1 Added themeing example
  • 0.1.0 Intitial version

Author

Martin Wildfeuer, mwfire@mwfire.de for Orderella Ltd., orderella.co.uk
You might also want to follow us on Twitter, @theMWFire | @Orderella

Thank you

Thanks to everyone who uses, enhances and improves this library, especially the contributors.

Images in the sample project

The sample project features two images from Markus Spiske raumrot.com:
Vintage Car One | Vintage Car Two
Thanks a lot for providing these :)

License

PopupDialog is available under the MIT license. See the LICENSE file for more info.

About

A simple, customizable popup dialog for iOS written in Swift. Replaces UIAlertController alert style.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

VersionLicensePlatformCarthage compatiblecodebeat badgeBuild Status MasterBuild Status Development

Introduction

Popup Dialog is a simple, customizable popup dialog written in Swift.

Features

  • Easy to use API with hardly any boilerplate code
  • Convenient default view with image, title, message
  • Supports custom view controllers
  • Slick transition animations
  • Fully themeable via appearance, including fonts, colors, corner radius, shadow, overlay color and blur, etc.
  • Can be dismissed via swipe and background tap
  • Objective-C compatible
  • Works on all screens and devices supporting iOS 8.0+

Installation

Cocoapods

PopupDialog is available through CocoaPods. For best results with Swift 3, I recommend installing CocoaPods version 1.1.0 (which might be a prerelease as of this release). Simply add the following to your Podfile:

use_frameworks!target'<Your Target Name>'pod'PopupDialog','~> 0.5'

Please note that this version is compatiable with iOS8

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. A minimum version of 0.17 is required.

To install, simply add the following lines to your Cartfile:

github"Orderella/PopupDialog" ~> 0.5

Manually

If you prefer not to use either of the above mentioned dependency managers, you can integrate PopupDialog into your project manually by adding the files contained in the Classes folder to your project.

Example

You can find this and more example projects in the repo. To run it, clone the repo, and run pod install from the Example directory first.

import PopupDialog
// Prepare the popup assets
lettitle="THIS IS THE DIALOG TITLE"letmessage="This is the message section of the popup dialog default view"letimage=UIImage(named:"pexels-photo-103290")
// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Create buttons
letbuttonOne=CancelButton(title:"CANCEL"){print("You canceled the car dialog.")}letbuttonTwo=DefaultButton(title:"ADMIRE CAR"){print("What a beauty!")}letbuttonThree=DefaultButton(title:"BUY CAR", height:60){print("Ah, maybe next time :)")}
// Add buttons to dialog
// Alternatively, you can use popup.addButton(buttonOne)
// to add a single button
popup.addButtons([buttonOne, buttonTwo, buttonThree])
// Present dialog
self.present(popup, animated:true, completion:nil)

Usage

PopupDialog is a subclass of UIViewController and as such can be added to your view controller modally. You can initialize it either with the handy default view or a custom view controller.

Default Dialog

publicconvenienceinit(
title:String?,
message:String?,
image:UIImage?=nil,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

The default dialog initializer is a convenient way of creating a popup with image, title and message (see image one and two).

Bascially, all parameters are optional, although this makes no sense at all. You want to at least add a message and a single button, otherwise the dialog can't be dismissed, unless you do it manually.

If you provide an image it will be pinned to the top/left/right of the dialog. The ratio of the image will be used to set the height of the image view, so no distortion will occur.

Custom View Controller

publicinit(
viewController:UIViewController,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

You can pass your own view controller to PopupDialog (see image three). It is accessible via the viewController property of PopupDialog, which has to be casted to your view controllers class to access its properties. Make sure the custom view defines all constraints needed, so you don't run into any autolayout issues.

Buttons are added below the controllers view, however, these buttons are optional. If you decide to not add any buttons, you have to take care of dismissing the dialog manually. Being a subclass of view controller, this can be easily done via dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?).

Transition Animations

You can set a transition animation style with .BounceUp being the default. The following transition styles are available

publicenumPopupDialogTransitionStyle:Int{case bounceUp
case bounceDown
case zoomIn
case fadeIn
}

Button Alignment

Buttons can be distributed either .Horizontal or .Vertical, with the latter being the default. Please note distributing buttons horizontally might not be a good idea if you have more than two buttons.

publicenumUILayoutConstraintAxis:Int{case horizontal
case vertical
}

Gesture Dismissal

Gesture dismissal allows your dialog being dismissed either by a background tap or by swiping the dialog down. By default, this is set to true. You can prevent this behavior by setting gestureDismissal to false in the initializer.

Completion

This completion handler is called when the dialog was dismissed. This is especially useful for catching a gesture dismissal.

Default Dialog Properties

If you are using the default dialog, you can change selected properties at runtime:

// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Present dialog
self.present(popup, animated:true, completion:nil)
// Get the default view controller and cast it
// Unfortunately, casting is necessary to support Objective-C
letvc= popup.viewController as!PopupDialogDefaultViewController
// Set dialog properties
vc.image =UIImage(...)
vc.titleText ="..."
vc.messageText ="..."
vc.buttonAlignment =.horizontal
vc.transitionStyle =.bounceUp

Styling PopupDialog

Appearance is the preferred way of customizing the style of PopupDialog. The idea of PopupDialog is to define a theme in a single place, without having to provide style settings with every single instantiation. This way, creating a PopupDialog requires only minimal code to be written and no "wrappers".

This makes even more sense, as popup dialogs and alerts are supposed to look consistent throughout the app, that is, maintain a single style.

Dialog Default View Appearance Settings

If you are using the default popup view, the following appearance settings are available:

vardialogAppearance=PopupDialogDefaultView.appearance()
dialogAppearance.backgroundColor =UIColor.white
dialogAppearance.titleFont =UIFont.boldSystemFont(ofSize:14)
dialogAppearance.titleColor =UIColor(white:0.4, alpha:1)
dialogAppearance.titleTextAlignment =.center
dialogAppearance.messageFont =UIFont.systemFont(ofSize:14)
dialogAppearance.messageColor =UIColor(white:0.6, alpha:1)
dialogAppearance.messageTextAlignment =.center
dialogAppearance.cornerRadius =4
dialogAppearance.shadowEnabled =true
dialogAppearance.shadowColor =UIColor.black

Overlay View Appearance Settings

This refers to the view that is used as an overlay above the underlying view controller but below the popup dialog view. If that makes sense ;)

letoverlayAppearance=PopupDialogOverlayView.appearance()
overlayAppearance.color =UIColor.black
overlayAppearance.blurRadius =20
overlayAppearance.blurEnabled =true
overlayAppearance.liveBlur =false
overlayAppearance.opacity =0.7

Note

Turning on liveBlur, that is realtime updates of the background view, results in a significantly higher CPU usage /power consumption and is therefore turned off by default now. Choose wisely whether you need this feature or not ;)

Button Appearance Settings

The standard button classes available are DefaultButton, CancelButton and DestructiveButton. All buttons feature the same appearance settings and can be styled seperately.

varbuttonAppearance=DefaultButton.appearance()
// Default button
buttonAppearance.titleFont =UIFont.systemFont(ofSize:14)
buttonAppearance.titleColor =UIColor(red:0.25, green:0.53, blue:0.91, alpha:1)
buttonAppearance.buttonColor =UIColor.clear
buttonAppearance.separatorColor =UIColor(white:0.9, alpha:1)
// Below, only the differences are highlighted
// Cancel button
CancelButton.appearance().titleColor =UIColor.lightGray
// Destructive button
DestructiveButton.appearance().titleColor =UIColor.red

Moreover, you can create a custom button by subclassing PopupDialogButton. The following example creates a solid blue button, featuring a bold white title font. Separators are invisble.

publicfinalclassSolidBlueButton:PopupDialogButton{overridepublicfunc setupView(){
defaultFont =UIFont.boldSystemFont(ofSize:16)
defaultTitleColor =UIColor.white
defaultButtonColor =UIColor.blue
defaultSeparatorColor =UIColor.clear
super.setupView()}}

These buttons can be customized with the appearance settings given above as well.

Dark mode example

The following is an example of a Dark Mode theme. You can find this in the Example project AppDelegate, just uncomment it to apply the custom appearance.

// Customize dialog appearance
letpv=PopupDialogDefaultView.appearance()
pv.titleFont =UIFont(name:"HelveticaNeue-Light", size:16)!
pv.titleColor =UIColor.white
pv.messageFont =UIFont(name:"HelveticaNeue", size:14)!
pv.messageColor =UIColor(white:0.8, alpha:1)
// Customize the container view appearance
letpcv=PopupDialogContainerView.appearance()
pcv.backgroundColor =UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00)
pcv.cornerRadius =2
pcv.shadowEnabled =true
pcv.shadowColor =UIColor.black
// Customize overlay appearance
letov=PopupDialogOverlayView.appearance()
ov.blurEnabled =true
ov.blurRadius =30
ov.liveBlur =true
ov.opacity =0.7
ov.color =UIColor.black
// Customize default button appearance
letdb=DefaultButton.appearance()
db.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
db.titleColor =UIColor.white
db.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
db.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)
// Customize cancel button appearance
letcb=CancelButton.appearance()
cb.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
cb.titleColor =UIColor(white:0.6, alpha:1)
cb.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
cb.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)

I can see that there is room for more customization options. I might add more of them over time.

Screen sizes and rotation

Rotation and all screen sizes are supported. However, the dialog will never exceed a width of 340 points. This way, the dialog won't be too big on devices like iPads. However, landscape mode will not work well if the height of the dialog exceeds the width of the screen.

Working with text fields

If you are using text fields in your custom view controller, popup dialog makes sure that the dialog is positioned above the keybord whenever it appears. You can opt out of this behaviour by setting keyboardShiftsView to false on a PopupDialog.

Testing

PopupDialog exposes a nice and handy method that lets you trigger a button tap programmatically:

publicfunc tapButtonWithIndex(index:Int)

Other than that, PopupDialog unit tests are included in the root folder.

Objective-C

PopupDialog can be used in Objective-C projects as well. Here is a basic example:

#import<PopupDialog/PopupDialog-Swift.h>
PopupDialog *popup = [[PopupDialog alloc] initWithTitle:@"TEST"message:@"This is a test message!"image:nilbuttonAlignment:UILayoutConstraintAxisHorizontal
transitionStyle:PopupDialogTransitionStyleBounceUp
gestureDismissal:YEScompletion:nil];
CancelButton *cancel = [[CancelButton alloc] initWithTitle:@"CANCEL"dismissOnTap:YESaction:^{
// Default action
}];
DefaultButton *ok = [[DefaultButton alloc] initWithTitle:@"OK"dismissOnTap:YESaction:^{
// Ok action
}];
[popup addButtons: @[cancel, ok]];
[selfpresentViewController:popup animated:YEScompletion:nil];

Requirements

Minimum requirement is iOS 8.0. This dialog was written with Swift 3, for 2.2 compatible versions please specify the X release.

Changelog

  • 0.5.4 Fixed bug where blur view would reveal hidden layer
    Improved view controller lifecycle handling
    Scroll views can now be used with gesture dismissal
  • 0.5.3 Fixed memory leak with custom view controllers
    Added UI automation & snapshot tests
  • 0.5.2 Fixed image scaling for default view
  • 0.5.1 Introduced custom button height parameter
    Reintroduced iOS8 compatibility
  • 0.5.0 Swift 3 compatibility / removed iOS8
  • 0.4.0 iOS 8 compatibility
  • 0.3.3 Fixes buttons being added multiple times
  • 0.3.2 Dialog repositioning when interacting with keyboard
    Non dismissable buttons option
    Additional completion handler when dialog is dismissed
  • 0.3.1 Fixed Carthage issues
  • 0.3.0 Objective-C compatibility
  • 0.2.2 Turned off liveBlur by default to increase performance
  • 0.2.1 Dismiss via background tap or swipe down transition
  • 0.2.0 You can now pass custom view controllers to the dialog. This introduces breaking changes.
  • 0.1.6 Defer button action until animation completes
  • 0.1.5 Exposed dialog properties
    (titleText, messageText, image, buttonAlignment, transitionStyle)
  • 0.1.4 Pick transition animation style
  • 0.1.3 Big screen support
    Exposed basic shadow appearance
  • 0.1.2 Exposed blur and overlay appearance
  • 0.1.1 Added themeing example
  • 0.1.0 Intitial version

Author

Martin Wildfeuer, mwfire@mwfire.de for Orderella Ltd., orderella.co.uk
You might also want to follow us on Twitter, @theMWFire | @Orderella

Thank you

Thanks to everyone who uses, enhances and improves this library, especially the contributors.

Images in the sample project

The sample project features two images from Markus Spiske raumrot.com:
Vintage Car One | Vintage Car Two
Thanks a lot for providing these :)

License

PopupDialog is available under the MIT license. See the LICENSE file for more info.

About

A simple, customizable popup dialog for iOS written in Swift. Replaces UIAlertController alert style.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

VersionLicensePlatformCarthage compatiblecodebeat badgeBuild Status MasterBuild Status Development

Introduction

Popup Dialog is a simple, customizable popup dialog written in Swift.

Features

  • Easy to use API with hardly any boilerplate code
  • Convenient default view with image, title, message
  • Supports custom view controllers
  • Slick transition animations
  • Fully themeable via appearance, including fonts, colors, corner radius, shadow, overlay color and blur, etc.
  • Can be dismissed via swipe and background tap
  • Objective-C compatible
  • Works on all screens and devices supporting iOS 8.0+

Installation

Cocoapods

PopupDialog is available through CocoaPods. For best results with Swift 3, I recommend installing CocoaPods version 1.1.0 (which might be a prerelease as of this release). Simply add the following to your Podfile:

use_frameworks!target'<Your Target Name>'pod'PopupDialog','~> 0.5'

Please note that this version is compatiable with iOS8

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. A minimum version of 0.17 is required.

To install, simply add the following lines to your Cartfile:

github"Orderella/PopupDialog" ~> 0.5

Manually

If you prefer not to use either of the above mentioned dependency managers, you can integrate PopupDialog into your project manually by adding the files contained in the Classes folder to your project.

Example

You can find this and more example projects in the repo. To run it, clone the repo, and run pod install from the Example directory first.

import PopupDialog
// Prepare the popup assets
lettitle="THIS IS THE DIALOG TITLE"letmessage="This is the message section of the popup dialog default view"letimage=UIImage(named:"pexels-photo-103290")
// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Create buttons
letbuttonOne=CancelButton(title:"CANCEL"){print("You canceled the car dialog.")}letbuttonTwo=DefaultButton(title:"ADMIRE CAR"){print("What a beauty!")}letbuttonThree=DefaultButton(title:"BUY CAR", height:60){print("Ah, maybe next time :)")}
// Add buttons to dialog
// Alternatively, you can use popup.addButton(buttonOne)
// to add a single button
popup.addButtons([buttonOne, buttonTwo, buttonThree])
// Present dialog
self.present(popup, animated:true, completion:nil)

Usage

PopupDialog is a subclass of UIViewController and as such can be added to your view controller modally. You can initialize it either with the handy default view or a custom view controller.

Default Dialog

publicconvenienceinit(
title:String?,
message:String?,
image:UIImage?=nil,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

The default dialog initializer is a convenient way of creating a popup with image, title and message (see image one and two).

Bascially, all parameters are optional, although this makes no sense at all. You want to at least add a message and a single button, otherwise the dialog can't be dismissed, unless you do it manually.

If you provide an image it will be pinned to the top/left/right of the dialog. The ratio of the image will be used to set the height of the image view, so no distortion will occur.

Custom View Controller

publicinit(
viewController:UIViewController,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

You can pass your own view controller to PopupDialog (see image three). It is accessible via the viewController property of PopupDialog, which has to be casted to your view controllers class to access its properties. Make sure the custom view defines all constraints needed, so you don't run into any autolayout issues.

Buttons are added below the controllers view, however, these buttons are optional. If you decide to not add any buttons, you have to take care of dismissing the dialog manually. Being a subclass of view controller, this can be easily done via dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?).

Transition Animations

You can set a transition animation style with .BounceUp being the default. The following transition styles are available

publicenumPopupDialogTransitionStyle:Int{case bounceUp
case bounceDown
case zoomIn
case fadeIn
}

Button Alignment

Buttons can be distributed either .Horizontal or .Vertical, with the latter being the default. Please note distributing buttons horizontally might not be a good idea if you have more than two buttons.

publicenumUILayoutConstraintAxis:Int{case horizontal
case vertical
}

Gesture Dismissal

Gesture dismissal allows your dialog being dismissed either by a background tap or by swiping the dialog down. By default, this is set to true. You can prevent this behavior by setting gestureDismissal to false in the initializer.

Completion

This completion handler is called when the dialog was dismissed. This is especially useful for catching a gesture dismissal.

Default Dialog Properties

If you are using the default dialog, you can change selected properties at runtime:

// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Present dialog
self.present(popup, animated:true, completion:nil)
// Get the default view controller and cast it
// Unfortunately, casting is necessary to support Objective-C
letvc= popup.viewController as!PopupDialogDefaultViewController
// Set dialog properties
vc.image =UIImage(...)
vc.titleText ="..."
vc.messageText ="..."
vc.buttonAlignment =.horizontal
vc.transitionStyle =.bounceUp

Styling PopupDialog

Appearance is the preferred way of customizing the style of PopupDialog. The idea of PopupDialog is to define a theme in a single place, without having to provide style settings with every single instantiation. This way, creating a PopupDialog requires only minimal code to be written and no "wrappers".

This makes even more sense, as popup dialogs and alerts are supposed to look consistent throughout the app, that is, maintain a single style.

Dialog Default View Appearance Settings

If you are using the default popup view, the following appearance settings are available:

vardialogAppearance=PopupDialogDefaultView.appearance()
dialogAppearance.backgroundColor =UIColor.white
dialogAppearance.titleFont =UIFont.boldSystemFont(ofSize:14)
dialogAppearance.titleColor =UIColor(white:0.4, alpha:1)
dialogAppearance.titleTextAlignment =.center
dialogAppearance.messageFont =UIFont.systemFont(ofSize:14)
dialogAppearance.messageColor =UIColor(white:0.6, alpha:1)
dialogAppearance.messageTextAlignment =.center
dialogAppearance.cornerRadius =4
dialogAppearance.shadowEnabled =true
dialogAppearance.shadowColor =UIColor.black

Overlay View Appearance Settings

This refers to the view that is used as an overlay above the underlying view controller but below the popup dialog view. If that makes sense ;)

letoverlayAppearance=PopupDialogOverlayView.appearance()
overlayAppearance.color =UIColor.black
overlayAppearance.blurRadius =20
overlayAppearance.blurEnabled =true
overlayAppearance.liveBlur =false
overlayAppearance.opacity =0.7

Note

Turning on liveBlur, that is realtime updates of the background view, results in a significantly higher CPU usage /power consumption and is therefore turned off by default now. Choose wisely whether you need this feature or not ;)

Button Appearance Settings

The standard button classes available are DefaultButton, CancelButton and DestructiveButton. All buttons feature the same appearance settings and can be styled seperately.

varbuttonAppearance=DefaultButton.appearance()
// Default button
buttonAppearance.titleFont =UIFont.systemFont(ofSize:14)
buttonAppearance.titleColor =UIColor(red:0.25, green:0.53, blue:0.91, alpha:1)
buttonAppearance.buttonColor =UIColor.clear
buttonAppearance.separatorColor =UIColor(white:0.9, alpha:1)
// Below, only the differences are highlighted
// Cancel button
CancelButton.appearance().titleColor =UIColor.lightGray
// Destructive button
DestructiveButton.appearance().titleColor =UIColor.red

Moreover, you can create a custom button by subclassing PopupDialogButton. The following example creates a solid blue button, featuring a bold white title font. Separators are invisble.

publicfinalclassSolidBlueButton:PopupDialogButton{overridepublicfunc setupView(){
defaultFont =UIFont.boldSystemFont(ofSize:16)
defaultTitleColor =UIColor.white
defaultButtonColor =UIColor.blue
defaultSeparatorColor =UIColor.clear
super.setupView()}}

These buttons can be customized with the appearance settings given above as well.

Dark mode example

The following is an example of a Dark Mode theme. You can find this in the Example project AppDelegate, just uncomment it to apply the custom appearance.

// Customize dialog appearance
letpv=PopupDialogDefaultView.appearance()
pv.titleFont =UIFont(name:"HelveticaNeue-Light", size:16)!
pv.titleColor =UIColor.white
pv.messageFont =UIFont(name:"HelveticaNeue", size:14)!
pv.messageColor =UIColor(white:0.8, alpha:1)
// Customize the container view appearance
letpcv=PopupDialogContainerView.appearance()
pcv.backgroundColor =UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00)
pcv.cornerRadius =2
pcv.shadowEnabled =true
pcv.shadowColor =UIColor.black
// Customize overlay appearance
letov=PopupDialogOverlayView.appearance()
ov.blurEnabled =true
ov.blurRadius =30
ov.liveBlur =true
ov.opacity =0.7
ov.color =UIColor.black
// Customize default button appearance
letdb=DefaultButton.appearance()
db.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
db.titleColor =UIColor.white
db.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
db.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)
// Customize cancel button appearance
letcb=CancelButton.appearance()
cb.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
cb.titleColor =UIColor(white:0.6, alpha:1)
cb.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
cb.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)

I can see that there is room for more customization options. I might add more of them over time.

Screen sizes and rotation

Rotation and all screen sizes are supported. However, the dialog will never exceed a width of 340 points. This way, the dialog won't be too big on devices like iPads. However, landscape mode will not work well if the height of the dialog exceeds the width of the screen.

Working with text fields

If you are using text fields in your custom view controller, popup dialog makes sure that the dialog is positioned above the keybord whenever it appears. You can opt out of this behaviour by setting keyboardShiftsView to false on a PopupDialog.

Testing

PopupDialog exposes a nice and handy method that lets you trigger a button tap programmatically:

publicfunc tapButtonWithIndex(index:Int)

Other than that, PopupDialog unit tests are included in the root folder.

Objective-C

PopupDialog can be used in Objective-C projects as well. Here is a basic example:

#import<PopupDialog/PopupDialog-Swift.h>
PopupDialog *popup = [[PopupDialog alloc] initWithTitle:@"TEST"message:@"This is a test message!"image:nilbuttonAlignment:UILayoutConstraintAxisHorizontal
transitionStyle:PopupDialogTransitionStyleBounceUp
gestureDismissal:YEScompletion:nil];
CancelButton *cancel = [[CancelButton alloc] initWithTitle:@"CANCEL"dismissOnTap:YESaction:^{
// Default action
}];
DefaultButton *ok = [[DefaultButton alloc] initWithTitle:@"OK"dismissOnTap:YESaction:^{
// Ok action
}];
[popup addButtons: @[cancel, ok]];
[selfpresentViewController:popup animated:YEScompletion:nil];

Requirements

Minimum requirement is iOS 8.0. This dialog was written with Swift 3, for 2.2 compatible versions please specify the X release.

Changelog

  • 0.5.4 Fixed bug where blur view would reveal hidden layer
    Improved view controller lifecycle handling
    Scroll views can now be used with gesture dismissal
  • 0.5.3 Fixed memory leak with custom view controllers
    Added UI automation & snapshot tests
  • 0.5.2 Fixed image scaling for default view
  • 0.5.1 Introduced custom button height parameter
    Reintroduced iOS8 compatibility
  • 0.5.0 Swift 3 compatibility / removed iOS8
  • 0.4.0 iOS 8 compatibility
  • 0.3.3 Fixes buttons being added multiple times
  • 0.3.2 Dialog repositioning when interacting with keyboard
    Non dismissable buttons option
    Additional completion handler when dialog is dismissed
  • 0.3.1 Fixed Carthage issues
  • 0.3.0 Objective-C compatibility
  • 0.2.2 Turned off liveBlur by default to increase performance
  • 0.2.1 Dismiss via background tap or swipe down transition
  • 0.2.0 You can now pass custom view controllers to the dialog. This introduces breaking changes.
  • 0.1.6 Defer button action until animation completes
  • 0.1.5 Exposed dialog properties
    (titleText, messageText, image, buttonAlignment, transitionStyle)
  • 0.1.4 Pick transition animation style
  • 0.1.3 Big screen support
    Exposed basic shadow appearance
  • 0.1.2 Exposed blur and overlay appearance
  • 0.1.1 Added themeing example
  • 0.1.0 Intitial version

Author

Martin Wildfeuer, mwfire@mwfire.de for Orderella Ltd., orderella.co.uk
You might also want to follow us on Twitter, @theMWFire | @Orderella

Thank you

Thanks to everyone who uses, enhances and improves this library, especially the contributors.

Images in the sample project

The sample project features two images from Markus Spiske raumrot.com:
Vintage Car One | Vintage Car Two
Thanks a lot for providing these :)

License

PopupDialog is available under the MIT license. See the LICENSE file for more info.

About

A simple, customizable popup dialog for iOS written in Swift. Replaces UIAlertController alert style.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

VersionLicensePlatformCarthage compatiblecodebeat badgeBuild Status MasterBuild Status Development

Introduction

Popup Dialog is a simple, customizable popup dialog written in Swift.

Features

  • Easy to use API with hardly any boilerplate code
  • Convenient default view with image, title, message
  • Supports custom view controllers
  • Slick transition animations
  • Fully themeable via appearance, including fonts, colors, corner radius, shadow, overlay color and blur, etc.
  • Can be dismissed via swipe and background tap
  • Objective-C compatible
  • Works on all screens and devices supporting iOS 8.0+

Installation

Cocoapods

PopupDialog is available through CocoaPods. For best results with Swift 3, I recommend installing CocoaPods version 1.1.0 (which might be a prerelease as of this release). Simply add the following to your Podfile:

use_frameworks!target'<Your Target Name>'pod'PopupDialog','~> 0.5'

Please note that this version is compatiable with iOS8

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. A minimum version of 0.17 is required.

To install, simply add the following lines to your Cartfile:

github"Orderella/PopupDialog" ~> 0.5

Manually

If you prefer not to use either of the above mentioned dependency managers, you can integrate PopupDialog into your project manually by adding the files contained in the Classes folder to your project.

Example

You can find this and more example projects in the repo. To run it, clone the repo, and run pod install from the Example directory first.

import PopupDialog
// Prepare the popup assets
lettitle="THIS IS THE DIALOG TITLE"letmessage="This is the message section of the popup dialog default view"letimage=UIImage(named:"pexels-photo-103290")
// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Create buttons
letbuttonOne=CancelButton(title:"CANCEL"){print("You canceled the car dialog.")}letbuttonTwo=DefaultButton(title:"ADMIRE CAR"){print("What a beauty!")}letbuttonThree=DefaultButton(title:"BUY CAR", height:60){print("Ah, maybe next time :)")}
// Add buttons to dialog
// Alternatively, you can use popup.addButton(buttonOne)
// to add a single button
popup.addButtons([buttonOne, buttonTwo, buttonThree])
// Present dialog
self.present(popup, animated:true, completion:nil)

Usage

PopupDialog is a subclass of UIViewController and as such can be added to your view controller modally. You can initialize it either with the handy default view or a custom view controller.

Default Dialog

publicconvenienceinit(
title:String?,
message:String?,
image:UIImage?=nil,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

The default dialog initializer is a convenient way of creating a popup with image, title and message (see image one and two).

Bascially, all parameters are optional, although this makes no sense at all. You want to at least add a message and a single button, otherwise the dialog can't be dismissed, unless you do it manually.

If you provide an image it will be pinned to the top/left/right of the dialog. The ratio of the image will be used to set the height of the image view, so no distortion will occur.

Custom View Controller

publicinit(
viewController:UIViewController,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

You can pass your own view controller to PopupDialog (see image three). It is accessible via the viewController property of PopupDialog, which has to be casted to your view controllers class to access its properties. Make sure the custom view defines all constraints needed, so you don't run into any autolayout issues.

Buttons are added below the controllers view, however, these buttons are optional. If you decide to not add any buttons, you have to take care of dismissing the dialog manually. Being a subclass of view controller, this can be easily done via dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?).

Transition Animations

You can set a transition animation style with .BounceUp being the default. The following transition styles are available

publicenumPopupDialogTransitionStyle:Int{case bounceUp
case bounceDown
case zoomIn
case fadeIn
}

Button Alignment

Buttons can be distributed either .Horizontal or .Vertical, with the latter being the default. Please note distributing buttons horizontally might not be a good idea if you have more than two buttons.

publicenumUILayoutConstraintAxis:Int{case horizontal
case vertical
}

Gesture Dismissal

Gesture dismissal allows your dialog being dismissed either by a background tap or by swiping the dialog down. By default, this is set to true. You can prevent this behavior by setting gestureDismissal to false in the initializer.

Completion

This completion handler is called when the dialog was dismissed. This is especially useful for catching a gesture dismissal.

Default Dialog Properties

If you are using the default dialog, you can change selected properties at runtime:

// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Present dialog
self.present(popup, animated:true, completion:nil)
// Get the default view controller and cast it
// Unfortunately, casting is necessary to support Objective-C
letvc= popup.viewController as!PopupDialogDefaultViewController
// Set dialog properties
vc.image =UIImage(...)
vc.titleText ="..."
vc.messageText ="..."
vc.buttonAlignment =.horizontal
vc.transitionStyle =.bounceUp

Styling PopupDialog

Appearance is the preferred way of customizing the style of PopupDialog. The idea of PopupDialog is to define a theme in a single place, without having to provide style settings with every single instantiation. This way, creating a PopupDialog requires only minimal code to be written and no "wrappers".

This makes even more sense, as popup dialogs and alerts are supposed to look consistent throughout the app, that is, maintain a single style.

Dialog Default View Appearance Settings

If you are using the default popup view, the following appearance settings are available:

vardialogAppearance=PopupDialogDefaultView.appearance()
dialogAppearance.backgroundColor =UIColor.white
dialogAppearance.titleFont =UIFont.boldSystemFont(ofSize:14)
dialogAppearance.titleColor =UIColor(white:0.4, alpha:1)
dialogAppearance.titleTextAlignment =.center
dialogAppearance.messageFont =UIFont.systemFont(ofSize:14)
dialogAppearance.messageColor =UIColor(white:0.6, alpha:1)
dialogAppearance.messageTextAlignment =.center
dialogAppearance.cornerRadius =4
dialogAppearance.shadowEnabled =true
dialogAppearance.shadowColor =UIColor.black

Overlay View Appearance Settings

This refers to the view that is used as an overlay above the underlying view controller but below the popup dialog view. If that makes sense ;)

letoverlayAppearance=PopupDialogOverlayView.appearance()
overlayAppearance.color =UIColor.black
overlayAppearance.blurRadius =20
overlayAppearance.blurEnabled =true
overlayAppearance.liveBlur =false
overlayAppearance.opacity =0.7

Note

Turning on liveBlur, that is realtime updates of the background view, results in a significantly higher CPU usage /power consumption and is therefore turned off by default now. Choose wisely whether you need this feature or not ;)

Button Appearance Settings

The standard button classes available are DefaultButton, CancelButton and DestructiveButton. All buttons feature the same appearance settings and can be styled seperately.

varbuttonAppearance=DefaultButton.appearance()
// Default button
buttonAppearance.titleFont =UIFont.systemFont(ofSize:14)
buttonAppearance.titleColor =UIColor(red:0.25, green:0.53, blue:0.91, alpha:1)
buttonAppearance.buttonColor =UIColor.clear
buttonAppearance.separatorColor =UIColor(white:0.9, alpha:1)
// Below, only the differences are highlighted
// Cancel button
CancelButton.appearance().titleColor =UIColor.lightGray
// Destructive button
DestructiveButton.appearance().titleColor =UIColor.red

Moreover, you can create a custom button by subclassing PopupDialogButton. The following example creates a solid blue button, featuring a bold white title font. Separators are invisble.

publicfinalclassSolidBlueButton:PopupDialogButton{overridepublicfunc setupView(){
defaultFont =UIFont.boldSystemFont(ofSize:16)
defaultTitleColor =UIColor.white
defaultButtonColor =UIColor.blue
defaultSeparatorColor =UIColor.clear
super.setupView()}}

These buttons can be customized with the appearance settings given above as well.

Dark mode example

The following is an example of a Dark Mode theme. You can find this in the Example project AppDelegate, just uncomment it to apply the custom appearance.

// Customize dialog appearance
letpv=PopupDialogDefaultView.appearance()
pv.titleFont =UIFont(name:"HelveticaNeue-Light", size:16)!
pv.titleColor =UIColor.white
pv.messageFont =UIFont(name:"HelveticaNeue", size:14)!
pv.messageColor =UIColor(white:0.8, alpha:1)
// Customize the container view appearance
letpcv=PopupDialogContainerView.appearance()
pcv.backgroundColor =UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00)
pcv.cornerRadius =2
pcv.shadowEnabled =true
pcv.shadowColor =UIColor.black
// Customize overlay appearance
letov=PopupDialogOverlayView.appearance()
ov.blurEnabled =true
ov.blurRadius =30
ov.liveBlur =true
ov.opacity =0.7
ov.color =UIColor.black
// Customize default button appearance
letdb=DefaultButton.appearance()
db.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
db.titleColor =UIColor.white
db.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
db.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)
// Customize cancel button appearance
letcb=CancelButton.appearance()
cb.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
cb.titleColor =UIColor(white:0.6, alpha:1)
cb.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
cb.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)

I can see that there is room for more customization options. I might add more of them over time.

Screen sizes and rotation

Rotation and all screen sizes are supported. However, the dialog will never exceed a width of 340 points. This way, the dialog won't be too big on devices like iPads. However, landscape mode will not work well if the height of the dialog exceeds the width of the screen.

Working with text fields

If you are using text fields in your custom view controller, popup dialog makes sure that the dialog is positioned above the keybord whenever it appears. You can opt out of this behaviour by setting keyboardShiftsView to false on a PopupDialog.

Testing

PopupDialog exposes a nice and handy method that lets you trigger a button tap programmatically:

publicfunc tapButtonWithIndex(index:Int)

Other than that, PopupDialog unit tests are included in the root folder.

Objective-C

PopupDialog can be used in Objective-C projects as well. Here is a basic example:

#import<PopupDialog/PopupDialog-Swift.h>
PopupDialog *popup = [[PopupDialog alloc] initWithTitle:@"TEST"message:@"This is a test message!"image:nilbuttonAlignment:UILayoutConstraintAxisHorizontal
transitionStyle:PopupDialogTransitionStyleBounceUp
gestureDismissal:YEScompletion:nil];
CancelButton *cancel = [[CancelButton alloc] initWithTitle:@"CANCEL"dismissOnTap:YESaction:^{
// Default action
}];
DefaultButton *ok = [[DefaultButton alloc] initWithTitle:@"OK"dismissOnTap:YESaction:^{
// Ok action
}];
[popup addButtons: @[cancel, ok]];
[selfpresentViewController:popup animated:YEScompletion:nil];

Requirements

Minimum requirement is iOS 8.0. This dialog was written with Swift 3, for 2.2 compatible versions please specify the X release.

Changelog

  • 0.5.4 Fixed bug where blur view would reveal hidden layer
    Improved view controller lifecycle handling
    Scroll views can now be used with gesture dismissal
  • 0.5.3 Fixed memory leak with custom view controllers
    Added UI automation & snapshot tests
  • 0.5.2 Fixed image scaling for default view
  • 0.5.1 Introduced custom button height parameter
    Reintroduced iOS8 compatibility
  • 0.5.0 Swift 3 compatibility / removed iOS8
  • 0.4.0 iOS 8 compatibility
  • 0.3.3 Fixes buttons being added multiple times
  • 0.3.2 Dialog repositioning when interacting with keyboard
    Non dismissable buttons option
    Additional completion handler when dialog is dismissed
  • 0.3.1 Fixed Carthage issues
  • 0.3.0 Objective-C compatibility
  • 0.2.2 Turned off liveBlur by default to increase performance
  • 0.2.1 Dismiss via background tap or swipe down transition
  • 0.2.0 You can now pass custom view controllers to the dialog. This introduces breaking changes.
  • 0.1.6 Defer button action until animation completes
  • 0.1.5 Exposed dialog properties
    (titleText, messageText, image, buttonAlignment, transitionStyle)
  • 0.1.4 Pick transition animation style
  • 0.1.3 Big screen support
    Exposed basic shadow appearance
  • 0.1.2 Exposed blur and overlay appearance
  • 0.1.1 Added themeing example
  • 0.1.0 Intitial version

Author

Martin Wildfeuer, mwfire@mwfire.de for Orderella Ltd., orderella.co.uk
You might also want to follow us on Twitter, @theMWFire | @Orderella

Thank you

Thanks to everyone who uses, enhances and improves this library, especially the contributors.

Images in the sample project

The sample project features two images from Markus Spiske raumrot.com:
Vintage Car One | Vintage Car Two
Thanks a lot for providing these :)

License

PopupDialog is available under the MIT license. See the LICENSE file for more info.

About

A simple, customizable popup dialog for iOS written in Swift. Replaces UIAlertController alert style.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

VersionLicensePlatformCarthage compatiblecodebeat badgeBuild Status MasterBuild Status Development

Introduction

Popup Dialog is a simple, customizable popup dialog written in Swift.

Features

  • Easy to use API with hardly any boilerplate code
  • Convenient default view with image, title, message
  • Supports custom view controllers
  • Slick transition animations
  • Fully themeable via appearance, including fonts, colors, corner radius, shadow, overlay color and blur, etc.
  • Can be dismissed via swipe and background tap
  • Objective-C compatible
  • Works on all screens and devices supporting iOS 8.0+

Installation

Cocoapods

PopupDialog is available through CocoaPods. For best results with Swift 3, I recommend installing CocoaPods version 1.1.0 (which might be a prerelease as of this release). Simply add the following to your Podfile:

use_frameworks!target'<Your Target Name>'pod'PopupDialog','~> 0.5'

Please note that this version is compatiable with iOS8

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. A minimum version of 0.17 is required.

To install, simply add the following lines to your Cartfile:

github"Orderella/PopupDialog" ~> 0.5

Manually

If you prefer not to use either of the above mentioned dependency managers, you can integrate PopupDialog into your project manually by adding the files contained in the Classes folder to your project.

Example

You can find this and more example projects in the repo. To run it, clone the repo, and run pod install from the Example directory first.

import PopupDialog
// Prepare the popup assets
lettitle="THIS IS THE DIALOG TITLE"letmessage="This is the message section of the popup dialog default view"letimage=UIImage(named:"pexels-photo-103290")
// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Create buttons
letbuttonOne=CancelButton(title:"CANCEL"){print("You canceled the car dialog.")}letbuttonTwo=DefaultButton(title:"ADMIRE CAR"){print("What a beauty!")}letbuttonThree=DefaultButton(title:"BUY CAR", height:60){print("Ah, maybe next time :)")}
// Add buttons to dialog
// Alternatively, you can use popup.addButton(buttonOne)
// to add a single button
popup.addButtons([buttonOne, buttonTwo, buttonThree])
// Present dialog
self.present(popup, animated:true, completion:nil)

Usage

PopupDialog is a subclass of UIViewController and as such can be added to your view controller modally. You can initialize it either with the handy default view or a custom view controller.

Default Dialog

publicconvenienceinit(
title:String?,
message:String?,
image:UIImage?=nil,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

The default dialog initializer is a convenient way of creating a popup with image, title and message (see image one and two).

Bascially, all parameters are optional, although this makes no sense at all. You want to at least add a message and a single button, otherwise the dialog can't be dismissed, unless you do it manually.

If you provide an image it will be pinned to the top/left/right of the dialog. The ratio of the image will be used to set the height of the image view, so no distortion will occur.

Custom View Controller

publicinit(
viewController:UIViewController,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

You can pass your own view controller to PopupDialog (see image three). It is accessible via the viewController property of PopupDialog, which has to be casted to your view controllers class to access its properties. Make sure the custom view defines all constraints needed, so you don't run into any autolayout issues.

Buttons are added below the controllers view, however, these buttons are optional. If you decide to not add any buttons, you have to take care of dismissing the dialog manually. Being a subclass of view controller, this can be easily done via dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?).

Transition Animations

You can set a transition animation style with .BounceUp being the default. The following transition styles are available

publicenumPopupDialogTransitionStyle:Int{case bounceUp
case bounceDown
case zoomIn
case fadeIn
}

Button Alignment

Buttons can be distributed either .Horizontal or .Vertical, with the latter being the default. Please note distributing buttons horizontally might not be a good idea if you have more than two buttons.

publicenumUILayoutConstraintAxis:Int{case horizontal
case vertical
}

Gesture Dismissal

Gesture dismissal allows your dialog being dismissed either by a background tap or by swiping the dialog down. By default, this is set to true. You can prevent this behavior by setting gestureDismissal to false in the initializer.

Completion

This completion handler is called when the dialog was dismissed. This is especially useful for catching a gesture dismissal.

Default Dialog Properties

If you are using the default dialog, you can change selected properties at runtime:

// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Present dialog
self.present(popup, animated:true, completion:nil)
// Get the default view controller and cast it
// Unfortunately, casting is necessary to support Objective-C
letvc= popup.viewController as!PopupDialogDefaultViewController
// Set dialog properties
vc.image =UIImage(...)
vc.titleText ="..."
vc.messageText ="..."
vc.buttonAlignment =.horizontal
vc.transitionStyle =.bounceUp

Styling PopupDialog

Appearance is the preferred way of customizing the style of PopupDialog. The idea of PopupDialog is to define a theme in a single place, without having to provide style settings with every single instantiation. This way, creating a PopupDialog requires only minimal code to be written and no "wrappers".

This makes even more sense, as popup dialogs and alerts are supposed to look consistent throughout the app, that is, maintain a single style.

Dialog Default View Appearance Settings

If you are using the default popup view, the following appearance settings are available:

vardialogAppearance=PopupDialogDefaultView.appearance()
dialogAppearance.backgroundColor =UIColor.white
dialogAppearance.titleFont =UIFont.boldSystemFont(ofSize:14)
dialogAppearance.titleColor =UIColor(white:0.4, alpha:1)
dialogAppearance.titleTextAlignment =.center
dialogAppearance.messageFont =UIFont.systemFont(ofSize:14)
dialogAppearance.messageColor =UIColor(white:0.6, alpha:1)
dialogAppearance.messageTextAlignment =.center
dialogAppearance.cornerRadius =4
dialogAppearance.shadowEnabled =true
dialogAppearance.shadowColor =UIColor.black

Overlay View Appearance Settings

This refers to the view that is used as an overlay above the underlying view controller but below the popup dialog view. If that makes sense ;)

letoverlayAppearance=PopupDialogOverlayView.appearance()
overlayAppearance.color =UIColor.black
overlayAppearance.blurRadius =20
overlayAppearance.blurEnabled =true
overlayAppearance.liveBlur =false
overlayAppearance.opacity =0.7

Note

Turning on liveBlur, that is realtime updates of the background view, results in a significantly higher CPU usage /power consumption and is therefore turned off by default now. Choose wisely whether you need this feature or not ;)

Button Appearance Settings

The standard button classes available are DefaultButton, CancelButton and DestructiveButton. All buttons feature the same appearance settings and can be styled seperately.

varbuttonAppearance=DefaultButton.appearance()
// Default button
buttonAppearance.titleFont =UIFont.systemFont(ofSize:14)
buttonAppearance.titleColor =UIColor(red:0.25, green:0.53, blue:0.91, alpha:1)
buttonAppearance.buttonColor =UIColor.clear
buttonAppearance.separatorColor =UIColor(white:0.9, alpha:1)
// Below, only the differences are highlighted
// Cancel button
CancelButton.appearance().titleColor =UIColor.lightGray
// Destructive button
DestructiveButton.appearance().titleColor =UIColor.red

Moreover, you can create a custom button by subclassing PopupDialogButton. The following example creates a solid blue button, featuring a bold white title font. Separators are invisble.

publicfinalclassSolidBlueButton:PopupDialogButton{overridepublicfunc setupView(){
defaultFont =UIFont.boldSystemFont(ofSize:16)
defaultTitleColor =UIColor.white
defaultButtonColor =UIColor.blue
defaultSeparatorColor =UIColor.clear
super.setupView()}}

These buttons can be customized with the appearance settings given above as well.

Dark mode example

The following is an example of a Dark Mode theme. You can find this in the Example project AppDelegate, just uncomment it to apply the custom appearance.

// Customize dialog appearance
letpv=PopupDialogDefaultView.appearance()
pv.titleFont =UIFont(name:"HelveticaNeue-Light", size:16)!
pv.titleColor =UIColor.white
pv.messageFont =UIFont(name:"HelveticaNeue", size:14)!
pv.messageColor =UIColor(white:0.8, alpha:1)
// Customize the container view appearance
letpcv=PopupDialogContainerView.appearance()
pcv.backgroundColor =UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00)
pcv.cornerRadius =2
pcv.shadowEnabled =true
pcv.shadowColor =UIColor.black
// Customize overlay appearance
letov=PopupDialogOverlayView.appearance()
ov.blurEnabled =true
ov.blurRadius =30
ov.liveBlur =true
ov.opacity =0.7
ov.color =UIColor.black
// Customize default button appearance
letdb=DefaultButton.appearance()
db.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
db.titleColor =UIColor.white
db.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
db.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)
// Customize cancel button appearance
letcb=CancelButton.appearance()
cb.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
cb.titleColor =UIColor(white:0.6, alpha:1)
cb.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
cb.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)

I can see that there is room for more customization options. I might add more of them over time.

Screen sizes and rotation

Rotation and all screen sizes are supported. However, the dialog will never exceed a width of 340 points. This way, the dialog won't be too big on devices like iPads. However, landscape mode will not work well if the height of the dialog exceeds the width of the screen.

Working with text fields

If you are using text fields in your custom view controller, popup dialog makes sure that the dialog is positioned above the keybord whenever it appears. You can opt out of this behaviour by setting keyboardShiftsView to false on a PopupDialog.

Testing

PopupDialog exposes a nice and handy method that lets you trigger a button tap programmatically:

publicfunc tapButtonWithIndex(index:Int)

Other than that, PopupDialog unit tests are included in the root folder.

Objective-C

PopupDialog can be used in Objective-C projects as well. Here is a basic example:

#import<PopupDialog/PopupDialog-Swift.h>
PopupDialog *popup = [[PopupDialog alloc] initWithTitle:@"TEST"message:@"This is a test message!"image:nilbuttonAlignment:UILayoutConstraintAxisHorizontal
transitionStyle:PopupDialogTransitionStyleBounceUp
gestureDismissal:YEScompletion:nil];
CancelButton *cancel = [[CancelButton alloc] initWithTitle:@"CANCEL"dismissOnTap:YESaction:^{
// Default action
}];
DefaultButton *ok = [[DefaultButton alloc] initWithTitle:@"OK"dismissOnTap:YESaction:^{
// Ok action
}];
[popup addButtons: @[cancel, ok]];
[selfpresentViewController:popup animated:YEScompletion:nil];

Requirements

Minimum requirement is iOS 8.0. This dialog was written with Swift 3, for 2.2 compatible versions please specify the X release.

Changelog

  • 0.5.4 Fixed bug where blur view would reveal hidden layer
    Improved view controller lifecycle handling
    Scroll views can now be used with gesture dismissal
  • 0.5.3 Fixed memory leak with custom view controllers
    Added UI automation & snapshot tests
  • 0.5.2 Fixed image scaling for default view
  • 0.5.1 Introduced custom button height parameter
    Reintroduced iOS8 compatibility
  • 0.5.0 Swift 3 compatibility / removed iOS8
  • 0.4.0 iOS 8 compatibility
  • 0.3.3 Fixes buttons being added multiple times
  • 0.3.2 Dialog repositioning when interacting with keyboard
    Non dismissable buttons option
    Additional completion handler when dialog is dismissed
  • 0.3.1 Fixed Carthage issues
  • 0.3.0 Objective-C compatibility
  • 0.2.2 Turned off liveBlur by default to increase performance
  • 0.2.1 Dismiss via background tap or swipe down transition
  • 0.2.0 You can now pass custom view controllers to the dialog. This introduces breaking changes.
  • 0.1.6 Defer button action until animation completes
  • 0.1.5 Exposed dialog properties
    (titleText, messageText, image, buttonAlignment, transitionStyle)
  • 0.1.4 Pick transition animation style
  • 0.1.3 Big screen support
    Exposed basic shadow appearance
  • 0.1.2 Exposed blur and overlay appearance
  • 0.1.1 Added themeing example
  • 0.1.0 Intitial version

Author

Martin Wildfeuer, mwfire@mwfire.de for Orderella Ltd., orderella.co.uk
You might also want to follow us on Twitter, @theMWFire | @Orderella

Thank you

Thanks to everyone who uses, enhances and improves this library, especially the contributors.

Images in the sample project

The sample project features two images from Markus Spiske raumrot.com:
Vintage Car One | Vintage Car Two
Thanks a lot for providing these :)

License

PopupDialog is available under the MIT license. See the LICENSE file for more info.

About

A simple, customizable popup dialog for iOS written in Swift. Replaces UIAlertController alert style.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

VersionLicensePlatformCarthage compatiblecodebeat badgeBuild Status MasterBuild Status Development

Introduction

Popup Dialog is a simple, customizable popup dialog written in Swift.

Features

  • Easy to use API with hardly any boilerplate code
  • Convenient default view with image, title, message
  • Supports custom view controllers
  • Slick transition animations
  • Fully themeable via appearance, including fonts, colors, corner radius, shadow, overlay color and blur, etc.
  • Can be dismissed via swipe and background tap
  • Objective-C compatible
  • Works on all screens and devices supporting iOS 8.0+

Installation

Cocoapods

PopupDialog is available through CocoaPods. For best results with Swift 3, I recommend installing CocoaPods version 1.1.0 (which might be a prerelease as of this release). Simply add the following to your Podfile:

use_frameworks!target'<Your Target Name>'pod'PopupDialog','~> 0.5'

Please note that this version is compatiable with iOS8

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. A minimum version of 0.17 is required.

To install, simply add the following lines to your Cartfile:

github"Orderella/PopupDialog" ~> 0.5

Manually

If you prefer not to use either of the above mentioned dependency managers, you can integrate PopupDialog into your project manually by adding the files contained in the Classes folder to your project.

Example

You can find this and more example projects in the repo. To run it, clone the repo, and run pod install from the Example directory first.

import PopupDialog
// Prepare the popup assets
lettitle="THIS IS THE DIALOG TITLE"letmessage="This is the message section of the popup dialog default view"letimage=UIImage(named:"pexels-photo-103290")
// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Create buttons
letbuttonOne=CancelButton(title:"CANCEL"){print("You canceled the car dialog.")}letbuttonTwo=DefaultButton(title:"ADMIRE CAR"){print("What a beauty!")}letbuttonThree=DefaultButton(title:"BUY CAR", height:60){print("Ah, maybe next time :)")}
// Add buttons to dialog
// Alternatively, you can use popup.addButton(buttonOne)
// to add a single button
popup.addButtons([buttonOne, buttonTwo, buttonThree])
// Present dialog
self.present(popup, animated:true, completion:nil)

Usage

PopupDialog is a subclass of UIViewController and as such can be added to your view controller modally. You can initialize it either with the handy default view or a custom view controller.

Default Dialog

publicconvenienceinit(
title:String?,
message:String?,
image:UIImage?=nil,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

The default dialog initializer is a convenient way of creating a popup with image, title and message (see image one and two).

Bascially, all parameters are optional, although this makes no sense at all. You want to at least add a message and a single button, otherwise the dialog can't be dismissed, unless you do it manually.

If you provide an image it will be pinned to the top/left/right of the dialog. The ratio of the image will be used to set the height of the image view, so no distortion will occur.

Custom View Controller

publicinit(
viewController:UIViewController,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

You can pass your own view controller to PopupDialog (see image three). It is accessible via the viewController property of PopupDialog, which has to be casted to your view controllers class to access its properties. Make sure the custom view defines all constraints needed, so you don't run into any autolayout issues.

Buttons are added below the controllers view, however, these buttons are optional. If you decide to not add any buttons, you have to take care of dismissing the dialog manually. Being a subclass of view controller, this can be easily done via dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?).

Transition Animations

You can set a transition animation style with .BounceUp being the default. The following transition styles are available

publicenumPopupDialogTransitionStyle:Int{case bounceUp
case bounceDown
case zoomIn
case fadeIn
}

Button Alignment

Buttons can be distributed either .Horizontal or .Vertical, with the latter being the default. Please note distributing buttons horizontally might not be a good idea if you have more than two buttons.

publicenumUILayoutConstraintAxis:Int{case horizontal
case vertical
}

Gesture Dismissal

Gesture dismissal allows your dialog being dismissed either by a background tap or by swiping the dialog down. By default, this is set to true. You can prevent this behavior by setting gestureDismissal to false in the initializer.

Completion

This completion handler is called when the dialog was dismissed. This is especially useful for catching a gesture dismissal.

Default Dialog Properties

If you are using the default dialog, you can change selected properties at runtime:

// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Present dialog
self.present(popup, animated:true, completion:nil)
// Get the default view controller and cast it
// Unfortunately, casting is necessary to support Objective-C
letvc= popup.viewController as!PopupDialogDefaultViewController
// Set dialog properties
vc.image =UIImage(...)
vc.titleText ="..."
vc.messageText ="..."
vc.buttonAlignment =.horizontal
vc.transitionStyle =.bounceUp

Styling PopupDialog

Appearance is the preferred way of customizing the style of PopupDialog. The idea of PopupDialog is to define a theme in a single place, without having to provide style settings with every single instantiation. This way, creating a PopupDialog requires only minimal code to be written and no "wrappers".

This makes even more sense, as popup dialogs and alerts are supposed to look consistent throughout the app, that is, maintain a single style.

Dialog Default View Appearance Settings

If you are using the default popup view, the following appearance settings are available:

vardialogAppearance=PopupDialogDefaultView.appearance()
dialogAppearance.backgroundColor =UIColor.white
dialogAppearance.titleFont =UIFont.boldSystemFont(ofSize:14)
dialogAppearance.titleColor =UIColor(white:0.4, alpha:1)
dialogAppearance.titleTextAlignment =.center
dialogAppearance.messageFont =UIFont.systemFont(ofSize:14)
dialogAppearance.messageColor =UIColor(white:0.6, alpha:1)
dialogAppearance.messageTextAlignment =.center
dialogAppearance.cornerRadius =4
dialogAppearance.shadowEnabled =true
dialogAppearance.shadowColor =UIColor.black

Overlay View Appearance Settings

This refers to the view that is used as an overlay above the underlying view controller but below the popup dialog view. If that makes sense ;)

letoverlayAppearance=PopupDialogOverlayView.appearance()
overlayAppearance.color =UIColor.black
overlayAppearance.blurRadius =20
overlayAppearance.blurEnabled =true
overlayAppearance.liveBlur =false
overlayAppearance.opacity =0.7

Note

Turning on liveBlur, that is realtime updates of the background view, results in a significantly higher CPU usage /power consumption and is therefore turned off by default now. Choose wisely whether you need this feature or not ;)

Button Appearance Settings

The standard button classes available are DefaultButton, CancelButton and DestructiveButton. All buttons feature the same appearance settings and can be styled seperately.

varbuttonAppearance=DefaultButton.appearance()
// Default button
buttonAppearance.titleFont =UIFont.systemFont(ofSize:14)
buttonAppearance.titleColor =UIColor(red:0.25, green:0.53, blue:0.91, alpha:1)
buttonAppearance.buttonColor =UIColor.clear
buttonAppearance.separatorColor =UIColor(white:0.9, alpha:1)
// Below, only the differences are highlighted
// Cancel button
CancelButton.appearance().titleColor =UIColor.lightGray
// Destructive button
DestructiveButton.appearance().titleColor =UIColor.red

Moreover, you can create a custom button by subclassing PopupDialogButton. The following example creates a solid blue button, featuring a bold white title font. Separators are invisble.

publicfinalclassSolidBlueButton:PopupDialogButton{overridepublicfunc setupView(){
defaultFont =UIFont.boldSystemFont(ofSize:16)
defaultTitleColor =UIColor.white
defaultButtonColor =UIColor.blue
defaultSeparatorColor =UIColor.clear
super.setupView()}}

These buttons can be customized with the appearance settings given above as well.

Dark mode example

The following is an example of a Dark Mode theme. You can find this in the Example project AppDelegate, just uncomment it to apply the custom appearance.

// Customize dialog appearance
letpv=PopupDialogDefaultView.appearance()
pv.titleFont =UIFont(name:"HelveticaNeue-Light", size:16)!
pv.titleColor =UIColor.white
pv.messageFont =UIFont(name:"HelveticaNeue", size:14)!
pv.messageColor =UIColor(white:0.8, alpha:1)
// Customize the container view appearance
letpcv=PopupDialogContainerView.appearance()
pcv.backgroundColor =UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00)
pcv.cornerRadius =2
pcv.shadowEnabled =true
pcv.shadowColor =UIColor.black
// Customize overlay appearance
letov=PopupDialogOverlayView.appearance()
ov.blurEnabled =true
ov.blurRadius =30
ov.liveBlur =true
ov.opacity =0.7
ov.color =UIColor.black
// Customize default button appearance
letdb=DefaultButton.appearance()
db.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
db.titleColor =UIColor.white
db.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
db.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)
// Customize cancel button appearance
letcb=CancelButton.appearance()
cb.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
cb.titleColor =UIColor(white:0.6, alpha:1)
cb.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
cb.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)

I can see that there is room for more customization options. I might add more of them over time.

Screen sizes and rotation

Rotation and all screen sizes are supported. However, the dialog will never exceed a width of 340 points. This way, the dialog won't be too big on devices like iPads. However, landscape mode will not work well if the height of the dialog exceeds the width of the screen.

Working with text fields

If you are using text fields in your custom view controller, popup dialog makes sure that the dialog is positioned above the keybord whenever it appears. You can opt out of this behaviour by setting keyboardShiftsView to false on a PopupDialog.

Testing

PopupDialog exposes a nice and handy method that lets you trigger a button tap programmatically:

publicfunc tapButtonWithIndex(index:Int)

Other than that, PopupDialog unit tests are included in the root folder.

Objective-C

PopupDialog can be used in Objective-C projects as well. Here is a basic example:

#import<PopupDialog/PopupDialog-Swift.h>
PopupDialog *popup = [[PopupDialog alloc] initWithTitle:@"TEST"message:@"This is a test message!"image:nilbuttonAlignment:UILayoutConstraintAxisHorizontal
transitionStyle:PopupDialogTransitionStyleBounceUp
gestureDismissal:YEScompletion:nil];
CancelButton *cancel = [[CancelButton alloc] initWithTitle:@"CANCEL"dismissOnTap:YESaction:^{
// Default action
}];
DefaultButton *ok = [[DefaultButton alloc] initWithTitle:@"OK"dismissOnTap:YESaction:^{
// Ok action
}];
[popup addButtons: @[cancel, ok]];
[selfpresentViewController:popup animated:YEScompletion:nil];

Requirements

Minimum requirement is iOS 8.0. This dialog was written with Swift 3, for 2.2 compatible versions please specify the X release.

Changelog

  • 0.5.4 Fixed bug where blur view would reveal hidden layer
    Improved view controller lifecycle handling
    Scroll views can now be used with gesture dismissal
  • 0.5.3 Fixed memory leak with custom view controllers
    Added UI automation & snapshot tests
  • 0.5.2 Fixed image scaling for default view
  • 0.5.1 Introduced custom button height parameter
    Reintroduced iOS8 compatibility
  • 0.5.0 Swift 3 compatibility / removed iOS8
  • 0.4.0 iOS 8 compatibility
  • 0.3.3 Fixes buttons being added multiple times
  • 0.3.2 Dialog repositioning when interacting with keyboard
    Non dismissable buttons option
    Additional completion handler when dialog is dismissed
  • 0.3.1 Fixed Carthage issues
  • 0.3.0 Objective-C compatibility
  • 0.2.2 Turned off liveBlur by default to increase performance
  • 0.2.1 Dismiss via background tap or swipe down transition
  • 0.2.0 You can now pass custom view controllers to the dialog. This introduces breaking changes.
  • 0.1.6 Defer button action until animation completes
  • 0.1.5 Exposed dialog properties
    (titleText, messageText, image, buttonAlignment, transitionStyle)
  • 0.1.4 Pick transition animation style
  • 0.1.3 Big screen support
    Exposed basic shadow appearance
  • 0.1.2 Exposed blur and overlay appearance
  • 0.1.1 Added themeing example
  • 0.1.0 Intitial version

Author

Martin Wildfeuer, mwfire@mwfire.de for Orderella Ltd., orderella.co.uk
You might also want to follow us on Twitter, @theMWFire | @Orderella

Thank you

Thanks to everyone who uses, enhances and improves this library, especially the contributors.

Images in the sample project

The sample project features two images from Markus Spiske raumrot.com:
Vintage Car One | Vintage Car Two
Thanks a lot for providing these :)

License

PopupDialog is available under the MIT license. See the LICENSE file for more info.

About

A simple, customizable popup dialog for iOS written in Swift. Replaces UIAlertController alert style.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

VersionLicensePlatformCarthage compatiblecodebeat badgeBuild Status MasterBuild Status Development

Introduction

Popup Dialog is a simple, customizable popup dialog written in Swift.

Features

  • Easy to use API with hardly any boilerplate code
  • Convenient default view with image, title, message
  • Supports custom view controllers
  • Slick transition animations
  • Fully themeable via appearance, including fonts, colors, corner radius, shadow, overlay color and blur, etc.
  • Can be dismissed via swipe and background tap
  • Objective-C compatible
  • Works on all screens and devices supporting iOS 8.0+

Installation

Cocoapods

PopupDialog is available through CocoaPods. For best results with Swift 3, I recommend installing CocoaPods version 1.1.0 (which might be a prerelease as of this release). Simply add the following to your Podfile:

use_frameworks!target'<Your Target Name>'pod'PopupDialog','~> 0.5'

Please note that this version is compatiable with iOS8

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. A minimum version of 0.17 is required.

To install, simply add the following lines to your Cartfile:

github"Orderella/PopupDialog" ~> 0.5

Manually

If you prefer not to use either of the above mentioned dependency managers, you can integrate PopupDialog into your project manually by adding the files contained in the Classes folder to your project.

Example

You can find this and more example projects in the repo. To run it, clone the repo, and run pod install from the Example directory first.

import PopupDialog
// Prepare the popup assets
lettitle="THIS IS THE DIALOG TITLE"letmessage="This is the message section of the popup dialog default view"letimage=UIImage(named:"pexels-photo-103290")
// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Create buttons
letbuttonOne=CancelButton(title:"CANCEL"){print("You canceled the car dialog.")}letbuttonTwo=DefaultButton(title:"ADMIRE CAR"){print("What a beauty!")}letbuttonThree=DefaultButton(title:"BUY CAR", height:60){print("Ah, maybe next time :)")}
// Add buttons to dialog
// Alternatively, you can use popup.addButton(buttonOne)
// to add a single button
popup.addButtons([buttonOne, buttonTwo, buttonThree])
// Present dialog
self.present(popup, animated:true, completion:nil)

Usage

PopupDialog is a subclass of UIViewController and as such can be added to your view controller modally. You can initialize it either with the handy default view or a custom view controller.

Default Dialog

publicconvenienceinit(
title:String?,
message:String?,
image:UIImage?=nil,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

The default dialog initializer is a convenient way of creating a popup with image, title and message (see image one and two).

Bascially, all parameters are optional, although this makes no sense at all. You want to at least add a message and a single button, otherwise the dialog can't be dismissed, unless you do it manually.

If you provide an image it will be pinned to the top/left/right of the dialog. The ratio of the image will be used to set the height of the image view, so no distortion will occur.

Custom View Controller

publicinit(
viewController:UIViewController,
buttonAlignment:UILayoutConstraintAxis=.vertical,
transitionStyle:PopupDialogTransitionStyle=.bounceUp,
gestureDismissal:Bool=true,
completion:(()->Void)?=nil)

You can pass your own view controller to PopupDialog (see image three). It is accessible via the viewController property of PopupDialog, which has to be casted to your view controllers class to access its properties. Make sure the custom view defines all constraints needed, so you don't run into any autolayout issues.

Buttons are added below the controllers view, however, these buttons are optional. If you decide to not add any buttons, you have to take care of dismissing the dialog manually. Being a subclass of view controller, this can be easily done via dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?).

Transition Animations

You can set a transition animation style with .BounceUp being the default. The following transition styles are available

publicenumPopupDialogTransitionStyle:Int{case bounceUp
case bounceDown
case zoomIn
case fadeIn
}

Button Alignment

Buttons can be distributed either .Horizontal or .Vertical, with the latter being the default. Please note distributing buttons horizontally might not be a good idea if you have more than two buttons.

publicenumUILayoutConstraintAxis:Int{case horizontal
case vertical
}

Gesture Dismissal

Gesture dismissal allows your dialog being dismissed either by a background tap or by swiping the dialog down. By default, this is set to true. You can prevent this behavior by setting gestureDismissal to false in the initializer.

Completion

This completion handler is called when the dialog was dismissed. This is especially useful for catching a gesture dismissal.

Default Dialog Properties

If you are using the default dialog, you can change selected properties at runtime:

// Create the dialog
letpopup=PopupDialog(title: title, message: message, image: image)
// Present dialog
self.present(popup, animated:true, completion:nil)
// Get the default view controller and cast it
// Unfortunately, casting is necessary to support Objective-C
letvc= popup.viewController as!PopupDialogDefaultViewController
// Set dialog properties
vc.image =UIImage(...)
vc.titleText ="..."
vc.messageText ="..."
vc.buttonAlignment =.horizontal
vc.transitionStyle =.bounceUp

Styling PopupDialog

Appearance is the preferred way of customizing the style of PopupDialog. The idea of PopupDialog is to define a theme in a single place, without having to provide style settings with every single instantiation. This way, creating a PopupDialog requires only minimal code to be written and no "wrappers".

This makes even more sense, as popup dialogs and alerts are supposed to look consistent throughout the app, that is, maintain a single style.

Dialog Default View Appearance Settings

If you are using the default popup view, the following appearance settings are available:

vardialogAppearance=PopupDialogDefaultView.appearance()
dialogAppearance.backgroundColor =UIColor.white
dialogAppearance.titleFont =UIFont.boldSystemFont(ofSize:14)
dialogAppearance.titleColor =UIColor(white:0.4, alpha:1)
dialogAppearance.titleTextAlignment =.center
dialogAppearance.messageFont =UIFont.systemFont(ofSize:14)
dialogAppearance.messageColor =UIColor(white:0.6, alpha:1)
dialogAppearance.messageTextAlignment =.center
dialogAppearance.cornerRadius =4
dialogAppearance.shadowEnabled =true
dialogAppearance.shadowColor =UIColor.black

Overlay View Appearance Settings

This refers to the view that is used as an overlay above the underlying view controller but below the popup dialog view. If that makes sense ;)

letoverlayAppearance=PopupDialogOverlayView.appearance()
overlayAppearance.color =UIColor.black
overlayAppearance.blurRadius =20
overlayAppearance.blurEnabled =true
overlayAppearance.liveBlur =false
overlayAppearance.opacity =0.7

Note

Turning on liveBlur, that is realtime updates of the background view, results in a significantly higher CPU usage /power consumption and is therefore turned off by default now. Choose wisely whether you need this feature or not ;)

Button Appearance Settings

The standard button classes available are DefaultButton, CancelButton and DestructiveButton. All buttons feature the same appearance settings and can be styled seperately.

varbuttonAppearance=DefaultButton.appearance()
// Default button
buttonAppearance.titleFont =UIFont.systemFont(ofSize:14)
buttonAppearance.titleColor =UIColor(red:0.25, green:0.53, blue:0.91, alpha:1)
buttonAppearance.buttonColor =UIColor.clear
buttonAppearance.separatorColor =UIColor(white:0.9, alpha:1)
// Below, only the differences are highlighted
// Cancel button
CancelButton.appearance().titleColor =UIColor.lightGray
// Destructive button
DestructiveButton.appearance().titleColor =UIColor.red

Moreover, you can create a custom button by subclassing PopupDialogButton. The following example creates a solid blue button, featuring a bold white title font. Separators are invisble.

publicfinalclassSolidBlueButton:PopupDialogButton{overridepublicfunc setupView(){
defaultFont =UIFont.boldSystemFont(ofSize:16)
defaultTitleColor =UIColor.white
defaultButtonColor =UIColor.blue
defaultSeparatorColor =UIColor.clear
super.setupView()}}

These buttons can be customized with the appearance settings given above as well.

Dark mode example

The following is an example of a Dark Mode theme. You can find this in the Example project AppDelegate, just uncomment it to apply the custom appearance.

// Customize dialog appearance
letpv=PopupDialogDefaultView.appearance()
pv.titleFont =UIFont(name:"HelveticaNeue-Light", size:16)!
pv.titleColor =UIColor.white
pv.messageFont =UIFont(name:"HelveticaNeue", size:14)!
pv.messageColor =UIColor(white:0.8, alpha:1)
// Customize the container view appearance
letpcv=PopupDialogContainerView.appearance()
pcv.backgroundColor =UIColor(red:0.23, green:0.23, blue:0.27, alpha:1.00)
pcv.cornerRadius =2
pcv.shadowEnabled =true
pcv.shadowColor =UIColor.black
// Customize overlay appearance
letov=PopupDialogOverlayView.appearance()
ov.blurEnabled =true
ov.blurRadius =30
ov.liveBlur =true
ov.opacity =0.7
ov.color =UIColor.black
// Customize default button appearance
letdb=DefaultButton.appearance()
db.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
db.titleColor =UIColor.white
db.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
db.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)
// Customize cancel button appearance
letcb=CancelButton.appearance()
cb.titleFont =UIFont(name:"HelveticaNeue-Medium", size:14)!
cb.titleColor =UIColor(white:0.6, alpha:1)
cb.buttonColor =UIColor(red:0.25, green:0.25, blue:0.29, alpha:1.00)
cb.separatorColor =UIColor(red:0.20, green:0.20, blue:0.25, alpha:1.00)

I can see that there is room for more customization options. I might add more of them over time.

Screen sizes and rotation

Rotation and all screen sizes are supported. However, the dialog will never exceed a width of 340 points. This way, the dialog won't be too big on devices like iPads. However, landscape mode will not work well if the height of the dialog exceeds the width of the screen.

Working with text fields

If you are using text fields in your custom view controller, popup dialog makes sure that the dialog is positioned above the keybord whenever it appears. You can opt out of this behaviour by setting keyboardShiftsView to false on a PopupDialog.

Testing

PopupDialog exposes a nice and handy method that lets you trigger a button tap programmatically:

publicfunc tapButtonWithIndex(index:Int)

Other than that, PopupDialog unit tests are included in the root folder.

Objective-C

PopupDialog can be used in Objective-C projects as well. Here is a basic example:

#import<PopupDialog/PopupDialog-Swift.h>
PopupDialog *popup = [[PopupDialog alloc] initWithTitle:@"TEST"message:@"This is a test message!"image:nilbuttonAlignment:UILayoutConstraintAxisHorizontal
transitionStyle:PopupDialogTransitionStyleBounceUp
gestureDismissal:YEScompletion:nil];
CancelButton *cancel = [[CancelButton alloc] initWithTitle:@"CANCEL"dismissOnTap:YESaction:^{
// Default action
}];
DefaultButton *ok = [[DefaultButton alloc] initWithTitle:@"OK"dismissOnTap:YESaction:^{
// Ok action
}];
[popup addButtons: @[cancel, ok]];
[selfpresentViewController:popup animated:YEScompletion:nil];

Requirements

Minimum requirement is iOS 8.0. This dialog was written with Swift 3, for 2.2 compatible versions please specify the X release.

Changelog

  • 0.5.4 Fixed bug where blur view would reveal hidden layer
    Improved view controller lifecycle handling
    Scroll views can now be used with gesture dismissal
  • 0.5.3 Fixed memory leak with custom view controllers
    Added UI automation & snapshot tests
  • 0.5.2 Fixed image scaling for default view
  • 0.5.1 Introduced custom button height parameter
    Reintroduced iOS8 compatibility
  • 0.5.0 Swift 3 compatibility / removed iOS8
  • 0.4.0 iOS 8 compatibility
  • 0.3.3 Fixes buttons being added multiple times
  • 0.3.2 Dialog repositioning when interacting with keyboard
    Non dismissable buttons option
    Additional completion handler when dialog is dismissed
  • 0.3.1 Fixed Carthage issues
  • 0.3.0 Objective-C compatibility
  • 0.2.2 Turned off liveBlur by default to increase performance
  • 0.2.1 Dismiss via background tap or swipe down transition
  • 0.2.0 You can now pass custom view controllers to the dialog. This introduces breaking changes.
  • 0.1.6 Defer button action until animation completes
  • 0.1.5 Exposed dialog properties
    (titleText, messageText, image, buttonAlignment, transitionStyle)
  • 0.1.4 Pick transition animation style
  • 0.1.3 Big screen support
    Exposed basic shadow appearance
  • 0.1.2 Exposed blur and overlay appearance
  • 0.1.1 Added themeing example
  • 0.1.0 Intitial version

Author

Martin Wildfeuer, mwfire@mwfire.de for Orderella Ltd., orderella.co.uk
You might also want to follow us on Twitter, @theMWFire | @Orderella

Thank you

Thanks to everyone who uses, enhances and improves this library, especially the contributors.

Images in the sample project

The sample project features two images from Markus Spiske raumrot.com:
Vintage Car One | Vintage Car Two
Thanks a lot for providing these :)

License

PopupDialog is available under the MIT license. See the LICENSE file for more info.

About

A simple, customizable popup dialog for iOS written in Swift. Replaces UIAlertController alert style.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages