An easy to use UIAlertController builder for swift

Overview

LKAlertController

Circle CI Version License Platform

An easy to use UIAlertController builder for swift

Features

  • Short and simple syntax for creating both Alerts and ActionSheets from UIAlertController
  • String together methods to build more complex alerts and action sheets

Basic Usage

Alert

Alert(title: "Title", message: "Message")
	.addAction("Cancel")
	.addAction("Delete", style: .Destructive, handler: { _ in
		//Delete the object
	}).show()

Action Sheet

ActionSheet(title: "Title", message: "Message")
	.addAction("Cancel")
	.addAction("Delete", style: .Destructive, handler: { _ in
		//Delete the object
	}).show()

Detailed Usage

There are two seperate classes for creating UIAlertControllers, Alert, and ActionSheet. These are used to simplify the creation of the controller. Both can be initialized with or without both a title and message.

Alert()
ActionSheet()

Alert(title: "My title")
ActionSheet(title: "My title")

Alert(message: "My message")
ActionSheet(message: "My message")

Alert(title: "My title", message: "My message")
ActionSheet(title: "My title", message: "My message")

Add various actions to the controller using addAction. By default the button will be styled Cancel, but this can be configured on a per button basis, along with the handler that is called if the button is clicked. The possible styles are Cancel, Default, and Destructive. These methods can be strung together to add more buttons to the controller.

ActionSheet()
	.addAction("Cancel")
	.addAction("Save", style: .Default) {
		saveTheObject()
	}
	.addAction("Delete", style: Destructive) {
		deleteTheObject()
	}

The controller can be presented by calling show(). It will be animated by default.

Alert()
	.addAction("Okay")
	.show()
	
ActionSheet()
	.addAction("Delete", style: .Destructive) {
		delete()
	}
	.addAction("Cancel")
	.show(animated: true) {
		controllerWasPresented()
	}

Alert Specific Configuration

There is a shortcut on alerts to show with an okay button: showOkay

Alert(title: "Stuff has happened").showOkay()

You can also add your own shortcut show method. The following adds a showNevermind button that adds a Nevermind button and shows the alert.

extension Alert {
	///Shortcut method for adding a nevermind button and showing the alert
	public func showNevermind() {
		addAction("Nevermind", style: .Cancel, preferredAction: false, handler: nil)
		show()
	}
}

Text fields can also be added to alerts. To add a text field, initialize a text field first, and configure it, then pass it in with the alert. Note that text fields must be initialized as var rather than let

var textField = UITextField()
textField.placeholder = "Password"
textField.secureTextEntry = true

Alert().addTextfield(&textField).showOkay()

You can also configure the preferredAction property on an alert. This will highlight the text of the action, and pressing the return key on a physical keyboard will trigger this action.

Alert()
	.addAction("Okay", style: .Default, preferredAction: true)
	.show()

ActionSheet Specific Configuration

If presenting on iPad, ActionSheets need to be configured with where it is presenting from. This is done by using the setBarButtonItem or setPresentingSource function. Note that this has no effect on iPhone, so it is safe, and recommended, to call this method if your app supports both iPad and iPhone.

ActionSheet()
	.addAction("Delete", style: .Destructive) {
		delete()
	}
	.addAction("Cancel")
	.setBarButtonItem(navigationController.rightBarButtonItem)
	.show(animated: true) {
		controllerWasPresented()
	}
	
ActionSheet()
	.addAction("Delete", style: .Destructive) {
		delete()
	}
	.addAction("Cancel")
	.setPresentingSource(buttonThatWasPressed)
	.show(animated: true) {
		controllerWasPresented()
	}

##Testing

You can add an override for the show method to make it easy to add unit tests for your alerts.

func testDeleteOpensConfirmationAlert() {
	let expectation = expectationWithDescription("Show override")

	LKAlertController.overrideShowForTesting { (style, title, message, actions, fields) -> Void in 
		
		XCTAssertEquals(title, "Are you sure you want to delete?", "Alert title was incorrect")
		
		expectation.fulfill()
	}
	
	model.delete()
	
	//If the override is never called, and the expectation is not fulfilled, the test will fail
	waitForExpectations(0.5, handler: nil)
}

This will allow you to test the controller was presented as well as the title, message, actions and fields of the alert or action sheet.

Installation

LKAlertController is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "LKAlertController"

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate LKAlertController into your Xcode project using Carthage, specify it in your Cartfile:

github "lightningkite/LKAlertController"

Run carthage update to build the framework and drag the built LKAlertController.framework into your Xcode project.

Issues Questions and Contributing

Have an issue, or want to request a feature? Create an issue in github.

Want to contribute? Add yourself to the authors list, and create a pull request.

Author

Erik Sargent, [email protected]

License

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

Comments
  • Attempt to present UIAlertController on view not in the window hierarchy

    Attempt to present UIAlertController on view not in the window hierarchy

    Hiya,

    I've been looking for a nice method chain replacement for messy UIAlertController code for a while, so I gave yours a go! Unfortunately, I've run into a problem the first place I've tried to use it. =[ As part of performing Facebook login, I present a very simple dialog when all else fails as follows:

    Alert(title: "Error", message: "Unable to log in using Facebook. Please check your internet connection and try again.")
    .showOkay()
    

    This is called as the final part of the async callback chain (when the user has initiated FB login and it fails) and gives me the following error:

    Warning: Attempt to present <UIAlertController: 0x7fe3d35df020> on <FBSDKContainerViewController: 0x7fe3d5935af0> whose view is not in the window hierarchy!

    I'm guessing that the FBSDKContainer view controller is either being dismissed or isn't the right place to be launching this alert from. I've had a brief look at the logic used to select the controller and it looks sane... but I'm not exactly an expert on this. =/ Not sure where to go from here other than pull it out unless you have any ideas?

    Happy to help try and diagnose. I really like the simplicity of your approach.

    Kind regards, Andrew

    opened by afladmark 9
  • Add textfields to alert

    Add textfields to alert

    This adds simple convenience methods for adding textfields to a controller. Users can opt for a default textfield, optionally include placeholder text, or optionally configure the textfield for secure text entry.

    opened by akwilliamson 6
  • Cancel button always on left

    Cancel button always on left

    I can't get the Cancel button to be on the right. I tried switching the order of addAction and I also played around with addAction(String) vs addAction(String, style, handler).

           Alert(title: "Add", message: "test")
                    .addTextField(&nameField)
                    .addTextField(&descriptionField)
                    .addAction("Save", style: .default, handler: { _ in
                        print(nameField.text!)
                        print("Description: ", descriptionField.text!)
                    })
                    .addAction("Cancel")
                    .show()
    

    From Human Interface Guideline: In a two-button alert that proposes a potentially risky action, the button that cancels the action should be on the right (and light-colored). In a two-button alert that proposes a benign action that people are likely to want, the button that cancels the action should be on the left (and dark-colored).

    opened by nitrag 5
  • Update README.md for using text fields in alerts

    Update README.md for using text fields in alerts

    This includes instructions for variations on text field initialization and chaining text fields with other Alert methods. Note: Don't merge this PR until https://github.com/lightningkite/LKAlertController/pull/18 is merged.

    opened by akwilliamson 4
  • Styling

    Styling

    What do you think about adding functionality for styling? e.g. adding background color and tint color functionality? I'm not exactly sure what is and is not against the Apple guidelines for alerts.

    opened by akwilliamson 3
  • Add Required(Bool) to Textfield

    Add Required(Bool) to Textfield

    Adding the required option for addTextField(). This will make the preferredAction action button disabled until there is text input.

    Use case: You have an Alert+Textfield to name an object before saving, the name cannot be blank and you don't want to dismiss/reinit an alert to prompt the user for input again.

    .addTextField(&nameField, required: true )
    

    Note: only one required field is supported.

    OP: Please check variable declarations, I'm new to iOS, feedback appreciated!

    opened by nitrag 1
  • Require text in UITextField

    Require text in UITextField

    Loving this controller!

    Can we only enable the "Save" button if the textfield has input? I think it would require exposing the UIAlertViewController's primary action? Is that ok?

    Something like:

    @discardableResult
        public func addTextField( _ textField: inout UITextField, required: Bool = false) -> Alert {
    		var field: UITextField?
    		
            alertController.addTextField { [unowned textField] (tf: UITextField!) -> Void in
                tf.text = textField.text
                tf.placeholder = textField.placeholder
                tf.font = textField.font
                tf.textColor = textField.textColor
                tf.isSecureTextEntry = textField.isSecureTextEntry
                tf.keyboardType = textField.keyboardType
                tf.autocapitalizationType = textField.autocapitalizationType
                tf.autocorrectionType = textField.autocorrectionType
                
                field = tf
            }
    		
    		if let field = field {
    			textField = field
    		}
            
            if(required){
                NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextFieldTextDidChange, object: textField, queue: OperationQueue.main) { (notification) in
                    self.action.isEnabled = field?.text!.length > 0
                }
            }
            
            return self
        }
    

    based off: http://stackoverflow.com/questions/30596851/how-do-i-validate-textfields-in-an-uialertcontroller

    opened by nitrag 1
  • Carthage update fails

    Carthage update fails

    After upgrading to Xcode 8.1 (now with Swift 3.0.1) I had to rebuild LKAlertController, so I used carthage update. codesign failed, and it has something to do with the cocoa pod tests.

    Here are the relevant lines from the carthage-xcodebuild.xxxxxx.log file:

    Signing Identity:     "-"
    
    /usr/bin/codesign --force --sign - --timestamp=none /Users/home/Library/Developer/Xcode/DerivedData/LKAlertController-gfxpomyboovzwidrotfexklagyqa/Build/Products/Release-iphonesimulator/Pods-LKAlertController_Tests/LKAlertController.bundle
    /Users/home/Library/Developer/Xcode/DerivedData/LKAlertController-gfxpomyboovzwidrotfexklagyqa/Build/Products/Release-iphonesimulator/Pods-LKAlertController_Tests/LKAlertController.bundle: bundle format unrecognized, invalid, or unsuitable
    Command /usr/bin/codesign failed with exit code 1
    

    I think the key here is .../Pods-LKAlertController_Tests/LKAlertController.bundle: bundle format unrecognized, invalid, or unsuitable

    I got around this by forking your repo and removing the Pods-LKAlertController_Tests scheme.

    If anyone else needs a hot fix, use

    github "JamesPerlman/LKAlertController" "patch-1"

    in your Cartfile.

    I'm not sure how else to get around this, but I didn't spend too much time trying to figure this out.

    Am I the only one who uses Carthage and this framework? :P

    opened by JamesPerlman 1
  • Updated to Swift 3 (verify modification)

    Updated to Swift 3 (verify modification)

    Significant change on line 287 in method:

    public func addTextField(inout textField: UITextField) -> Alert {
    

    to

    public func addTextField(_ textField: UITextField) -> Alert {
    

    Why was the textfield inout? From my understanding this only makes sense if you want to modify an Alert's value while it's being displayed?

    opened by skofgar 1
  • Can't invoke addAction(_:style:handler) on ActionSheet instance

    Can't invoke addAction(_:style:handler) on ActionSheet instance

    When trying to invoke addAction on ActionSheet class instance with parameters title, style and handler, Xcode reports:

    Ambiguous use of addAction(_:style:handler)

    ActionSheet().addAction("Test", style: .Default, handler: { _ in print("Test") }).show()

    I've tried to use LKAlertController instance and it works:

    LKAlertController(style: .ActionSheet).addAction("Test", style: .Default, handler: { _ in print("Test") }).show()

    opened by paweljankowski 1
  • Possible to create UIAlertAction and add to the Sheet?

    Possible to create UIAlertAction and add to the Sheet?

    For example

    let action = UIAlertAction(title: "Sort By Month", style: .default) { (action) in } action.isEnabled = false ActionSheet(title: nil, message: nil).addAction(action).addAction("Dismiss").show()

    opened by nitish07 0
Releases(1.6.0)
Owner
Lightning Kite
Lightning Kite
Todo is an iOS App written in Swift. This app is used for an online video training course. This app demonstrates how to use UITableViewController.

Todo Todo is an iOS App written in Swift. This app is used for an online video training course. This app demonstrates how to use UITableViewController

Jake Lin 273 Dec 29, 2022
App that makes use of OpenWatherMap API

swiftui-weatherApp App that makes use of OpenWatherMap API Before running make sure you get your own API code: https://openweathermap.org/api and repl

Jose Chirinos Odio 1 Oct 15, 2021
The app demonstrates how to use Firebase in a SwiftUI iOS app

Firebase SwiftUIDemo app This app demonstrates how to use Firebase in a SwiftUI iOS app. Firebase Setup Go to firebase.com Click new project. Copy app

Andrew Gholson 0 Nov 28, 2021
A sample project how to use YOLOv5 in iOS

CoreML-YOLOv5 A sample project how to use YOLOv5 in iOS. You can run model on yo

MLBoy 32 Dec 19, 2022
CollectionComposer2 - Copy random image files from various sources to destination folder - ready to use

CollectionComposer2 This is a small tool to copy a random number of image files from different source folders to a destination folder. As an additiona

Holger Hinzberg 0 Jan 4, 2022
Weather - Use Open weather APIs to fetch live weather data

Weather ??️ Use Open weather APIs to fetch live weather data Use Core Location p

Vicky Lee 2 Jun 3, 2022
Ready use service for Firebase. Included interface, recored devices and notifications.

SPProfiling Ready use service with using Firebase. Included interface, manage auth process, recored devices and profile data. Installation Ready for u

Ivan Vorobei 13 Oct 29, 2022
COVID Safe Paths (based on Private Kit) is an open and privacy preserving system to use personal information to battle COVID

COVID Safe Paths is a mobile app for digital contract tracing (DCT) sponsored by Path Check a nonprofit and developed by a growing global community of engineers, designers, and contributors. Safe Paths is based on research originally conducted at the MIT Media Lab.

PathCheck Foundation 470 Nov 6, 2022
A simple to use iOS app with clean UI to calculate time until a specified date

A simple to use iOS app with clean UI to calculate time until a specified date.Added new feature that is now you can measure time from a specified date as well. Like time spent from the day you were born.

Dishant Nagpal 2 Feb 28, 2022
An experiment to use Firebase and React Native to build a wwdc.family app

wwdc.family This is an experiment to use Firebase and React Native to build a wwdc.family app. Don't use that source code as reference - I have no pri

WWDC Family 190 Feb 9, 2022
News App 📱 built to demonstrate the use of SwiftUI 3 features, Async/Await, CoreData and MVVM architecture pattern.

Box Feed News App ?? built to demonstrate the use of following features, SwiftUI 3 Async/Await AsyncImage List Refreshable Swipe Actions Separator Cor

Sameer Nawaz 113 Dec 20, 2022
Pegase is a beautifully easy tool to keep track of your financial life on all your macOS

Pegase ?? Features ?? Documentation Personal account software Pegase is a beautifully easy tool to keep track of your financial life on all your macOS

null 2 Oct 12, 2021
Easy BMI calculator to review optionals, segues and structs

BMI Calculator Our Goal The goal of this tutorial is to learn more about Optionals, solidify your understanding of the MVC design pattern and to intro

null 0 Oct 24, 2021
The demo project to show how to organize code to make SwiftUI apps easy to be test.

TestableApp I combined the idea to use functional programming instead of an loader instance in ModelView(I prefer to think of it as a service) and Res

VictorK 2 Jan 7, 2022
TodoList-iOS-master - DailyCheck makes it easy to manage your to-dos by date

Daily Check DailyCheck makes it easy to manage your to-dos by date. App Store Do

Kushal Shingote 1 Feb 5, 2022
This app is a native client for openHAB which allows easy access to your sitemaps

openHAB client for iOS Introduction This app is a native client for openHAB which allows easy access to your sitemaps. Beta releases are available on

openHAB 176 Dec 30, 2022
ToDoList - An ios app that help users to set their todos and make it easy to remember this todos

An ios app that help users to set their todos and make it easy to remember this todos by reminders them when todo time's up, this app make sure that you don't forget any todos that you want to do just give it to the app and let the app hundle it for you.

Ahmed Mahrous 1 Apr 25, 2022
ReactionButton is a control that allows developers to add this functionality to their apps in an easy way.

Since Facebook introduced reactions in 2016, it became a standard in several applications as a way for users to interact with content. ReactionButton is a control that allows developers to add this functionality to their apps in an easy way.

Jorge Ovalle 305 Oct 11, 2022
CZWeatherKit is a simple, extensible weather library for iOS, tvOS, and OS X that allows for easy fetching of weather data from various weather services.

CZWeatherKit is a simple, extensible weather library for iOS, tvOS, and OS X that allows for easy fetching of weather data from various weather services.

Comyar 455 Nov 20, 2022