Sheeeeeeeeet is a Swift library for custom action sheets.
Clone or download

README.md

Version Build Status CocoaPods Carthage Platform Swift 4.2 License Twitter: @danielsaidi

About Sheeeeeeeeet

Sheeeeeeeeet is a Swift library for creating custom action sheets. It comes with a collection of built-in items and can be extended with your own custom items.

Sheeeeeeeeet can be styled to look just like normal UIAlertControllers, or way different. You can apply a global style that applies to all sheets then override it for each action sheet. You can also apply custom styles to specific items.

Installation

CocoaPods

Add this to your Podfile then run pod install:

pod 'Sheeeeeeeeet'

Remember to use the generated workspace (not the project file) after installing.

Carthage

Add this to your Cartfile then run carthage update --platform iOS:

github "danielsaidi/Sheeeeeeeeet"

Once the update completes, link in the built framework from Carthage/Build.

Manual installation

To add Sheeeeeeeeet to your app without Carthage or CocoaPods, clone this repo and place it somewhere in your project folder. Then, add Sheeeeeeeeet.xcodeproj to your project and add Sheeeeeeeeet.framework as an embedded app binary under General and as a target dependency under Build Phases.

Creating and presenting an action sheet

To create an action sheet, just specify its items and callback action, like this:

func createStandardActionSheet() -> ActionSheet {
    let title = ActionSheetTitle(title: "Select an option")
    let item1 = ActionSheetItem(title: "Option 1", value: 1, image: image1)
    let item2 = ActionSheetItem(title: "Option 2", value: Car(), image: image2)
    let button = ActionSheetOkButton(title: "OK")
    return ActionSheet(items: items) { sheet, item in
        if let value = item.value as? Int { print("You selected the number 1") }
        if let value = item.value as? Car { print("You selected a car") }
        if item is ActionSheetOkButton { print("OK buttons has the value `true`") }
    }
}

To present the action sheet, just call any of its present functions, like this:

actionSheet.present(in: self, from: view)   // or
actionSheet.present(in: self, from: barButtonItem)

The from view will only be used if the action sheet it presented in a popover.

Domain-specific action sheets

When you use Sheeeeeeeeet in your apps, you may want the items to represent an app domain-specific type, e.g. a Movie, or an app-specific list options. Since the item value is of Any type, you can use any type or enum as value.

Specifying items after initialization

If you require a created action sheet instance to resolve which items to present (very common when you subclass ActionSheet), just create a sheet with no items then call setup(with:) once its created.

If you create a domain-specific action sheet, like a CarPickerActionSheet, you may have to use an injected dependency to load some data before you can populate your sheet with items. If the dependency is initializer injected, you first have to create the sheet with an empty item collection, then load the data using your injected dependency, then map the data to items, then finally inject these items into the sheet, using the setup(with:) approach described above.

Example Application

This repository contains an example app. Before you can run it, you must install Carthage (e.g. using brew) and run carthage update --platform iOS. You can then open the project and try out the different sheets and item types.

Action Sheet Components

Sheeeeeeeeet contains a set of built-in components that can be used to compose flexible sheets. To create custom items, just subclass any of the built-in types.

Items

Action sheet items are used to present options. Sheeeeeeeeet has the following built-in item types:

  • Item - A standard item that dismisses the sheet when tapped.
  • Single-select Item - Deselects all other single- select items in the same group when tapped. and by default dismisses the sheet.
  • Multi-Select Item - Doesn't deselect other items when tapped and doesn't dismiss the sheet.
  • Multi-Select Toggle - Toggles the selected state of all multi-select items in the same group.
  • Link Item - Renders as a link, but behaves like regular action sheet items.
  • Collection Item - A general item with an embedded collection view that can contain any type of cells.
  • Custom Item - A super-flexible item, that can use any custom view.

The standard item corresponds to a standard UIKit actionsheet action. It has a title, an optional subtitle and an image. It's the base class for all other item types, who also copies its standard appearance.

Every item has a tapBehavior, that determines how the item behaves when tapped. Some item types use .dismiss as default, while others use .none. You can set this property to any value on any item.

Buttons

Action sheet buttons are used to apply or discard an action sheet. Sheeeeeeeeet has the following built-in button types:

OK buttons have ActionSheetButton.ButtonType.ok as value, while cancel buttons have ActionSheetButton.ButtonType.cancel. You can always check the tapped item for isOkButton and isCancelButton as well, if you need to determine what the selection action should do.

Buttons are automatically separated from other items and presented in a separate list item. On popovers, however, they are added back to the end of the item list.

Titles

Titles are non-interactive text or space items. Sheeeeeeeeet has the following built-in title types:

You can add title components anywhere you want in your action sheets, although a title probably looks best topmost, a section title before an item section etc.

Header Views

If you set the headerView property of an action sheet, it will be displayed as a floating header above the action sheet. You can use any view as a header view.

Header views are completely removed in popovers, since popovers are solid bodies with no transparent background.

Appearance

Sheets can be globally styled by using the ActionSheetAppearance.standard. All action sheet items will then copy this appearance upon creation, and apply it to all items each time it refreshes its content.

If you want to apply a global style for all your action sheets, simply style the ActionSheetAppearance.standard property and all action sheets will be affected.

If you want to apply an individual style to a single action sheet, just style it using its appearance property (a copy of ActionSheetAppearance.standard), or completely replace it with a completely different appearance instance.

If you want to apply an individual style to a single action sheet item, just set its optional customAppearance property to any custom value. Just be careful to copy any other appearance, otherwise you'll affect the original style.

Have a look at the example app to see how global and individual appearances work.

Contact me

I hope you like this library. Feel free to reach out if you have questions or if you want to contribute in any way:

License

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