Created
February 20, 2020 13:39
-
-
Save felginep/289985cf8bb92699004099f75a621ea0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
struct Action { | |
let title: String | |
let style: UIAlertAction.Style | |
let action: () -> Void | |
} | |
extension Action { | |
static func `default`(_ title: String, action: @escaping () -> Void) -> [Action] { | |
return [Action(title: title, style: .default, action: action)] | |
} | |
static func destructive(_ title: String, action: @escaping () -> Void) -> [Action] { | |
return [Action(title: title, style: .destructive, action: action)] | |
} | |
static func cancel(_ title: String, action: @escaping () -> Void = {}) -> [Action] { | |
return [Action(title: title, style: .cancel, action: action)] | |
} | |
} | |
func makeAlertController(title: String, | |
message: String, | |
style: UIAlertController.Style, | |
actions: [Action]) -> UIAlertController { | |
let controller = UIAlertController( | |
title: title, | |
message: message, | |
preferredStyle: style | |
) | |
for action in actions { | |
let uiAction = UIAlertAction(title: action.title, style: action.style) { _ in | |
action.action() | |
} | |
controller.addAction(uiAction) | |
} | |
return controller | |
} | |
@_functionBuilder | |
struct ActionBuilder { | |
typealias Component = [Action] | |
static func buildBlock(_ children: Component...) -> Component { | |
return children.flatMap { $0 } | |
} | |
static func buildIf(_ component: Component?) -> Component { | |
return component ?? [] | |
} | |
static func buildEither(first component: Component) -> Component { | |
return component | |
} | |
static func buildEither(second component: Component) -> Component { | |
return component | |
} | |
} | |
func Alert(title: String, | |
message: String, | |
@ActionBuilder _ makeActions: () -> [Action]) -> UIAlertController { | |
makeAlertController( | |
title: title, | |
message: message, | |
style: .alert, | |
actions: makeActions() | |
) | |
} | |
func ActionSheet(title: String, | |
message: String, | |
@ActionBuilder _ makeActions: () -> [Action]) -> UIAlertController { | |
makeAlertController( | |
title: title, | |
message: message, | |
style: .actionSheet, | |
actions: makeActions() | |
) | |
} | |
func ForIn<S: Sequence>(_ sequence: S, | |
@ActionBuilder makeActions: (S.Element) -> [Action]) -> [Action] { | |
return sequence | |
.map(makeActions) // of type [[Action]] | |
.flatMap { $0 } // of type [Action] | |
} | |
let canEdit = true | |
let alertController = Alert(title: "Deletion", message: "Are you sure?") { | |
Action.default("Delete") { /* ... */ } | |
if canEdit { | |
Action.destructive("Edit") { /* ... */ } | |
} else { | |
Action.destructive("Share") { /* ... */ } | |
} | |
Action.cancel("Cancel") | |
} | |
let dynamicAlertController = Alert(title: "Title", message: "Message") { | |
ForIn(["Action1", "Action2"]) { string in | |
Action.default(string) { print(string) } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment