Last active
December 27, 2020 18:12
-
-
Save diegoventura/3168871fec9c6ef471d56a612681b8fa to your computer and use it in GitHub Desktop.
This file contains hidden or 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 SwiftUI | |
struct DialogButton { | |
enum ButtonType { | |
case destructive | |
case cancel | |
case `default` | |
} | |
let title: String | |
let type: ButtonType | |
let action: () -> Void | |
public init(title: String, type: ButtonType, action: @escaping () -> Void) { | |
self.title = title | |
self.type = type | |
self.action = action | |
} | |
} | |
struct ConfirmationDialog: ViewModifier { | |
@Binding var isPresented: Bool | |
let title: String | |
let message: String? | |
let buttons: [DialogButton] | |
let horizontalSizeClass: UserInterfaceSizeClass? | |
let onDismiss: () -> Void | |
func body(content: Content) -> some View { | |
content.if(horizontalSizeClass == .some(.regular)) { content in | |
content.popover(isPresented: $isPresented, content: popoverContent) | |
}.if(horizontalSizeClass == .some(.compact)) { content in | |
content.actionSheet(isPresented: $isPresented) { | |
ActionSheet(title: Text(self.title), message: Text(self.message ?? ""), buttons: sheetButtons) | |
} | |
} | |
} | |
private var sheetButtons: [ActionSheet.Button] { | |
UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = .teal | |
return buttons.map { button -> ActionSheet.Button in | |
switch button.type { | |
case .cancel: | |
return .cancel(button.action) | |
case .`default`: | |
return .default(Text(button.title), action: button.action) | |
case .destructive: | |
return .destructive(Text(button.title), action: button.action) | |
} | |
} | |
} | |
private var popoverButtons: [Button<Text>] { | |
return buttons.map { button in | |
switch button.type { | |
case .cancel: | |
return Button(action: { | |
button.action() | |
}, label: { | |
Text(button.title) | |
.bold() | |
.foregroundColor(Color.teal) | |
}) | |
case .`default`: | |
return Button(action: { | |
button.action() | |
}, label: { | |
Text(button.title) | |
.foregroundColor(Color.teal) | |
}) | |
case .destructive: | |
return Button(action: { | |
button.action() | |
}, label: { | |
Text(button.title) | |
.foregroundColor(Color(UIColor.systemRed)) | |
}) | |
} | |
} | |
} | |
private func popoverContent() -> some View { | |
return VStack(alignment: .center, spacing: 10) { | |
Text(title) | |
.font(.footnote) | |
.foregroundColor(Color.secondary) | |
.bold() | |
.padding(.top) | |
if message != nil { | |
Text(message ?? "") | |
.font(.footnote) | |
.foregroundColor(.secondary) | |
.multilineTextAlignment(.center) | |
.padding(.horizontal) | |
} | |
ForEach((0 ..< popoverButtons.count), id: \.self) { index in | |
Group { | |
Divider() | |
self.popoverButtons[index] | |
} | |
} | |
} | |
.buttonStyle(PlainButtonStyle()) | |
.frame(width: 200) | |
.padding(10) | |
.onDisappear { | |
self.onDismiss() | |
} | |
} | |
} |
This file contains hidden or 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 SwiftUI | |
struct MainView: View { | |
@State var isPresentingConfirmation: Bool | |
@Environment(\.horizontalSizeClass) private var horizontalSizeClass: UserInterfaceSizeClass? | |
var body: some View { | |
NavigationView { | |
Text("Hello world") | |
.navigationBarTitle("Welcome") | |
} | |
.navigationViewStyle(StackNavigationViewStyle()) | |
} | |
private var logoutButton: some View { | |
Button(action: { | |
self.isPresentingConfirmation = true | |
}, label: { | |
Text("Press me") | |
}) | |
.confirmationDialog(presented: $isPresentingConfirmation, title: "did you tap the button?", buttons: [ | |
DialogButton(title: "No", type: .default) { | |
self.isPresentingConfirmation = false | |
}, | |
DialogButton(title: "Yes", type: .destructive) { | |
self.isPresentingConfirmation = false | |
}, | |
DialogButton(title: "Cancel", type: .cancel) { | |
self.isPresentingConfirmation = false | |
} | |
], horizontalSizeClass: horizontalSizeClass) { | |
self.isPresentingConfirmation = false | |
} | |
} | |
} |
This file contains hidden or 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 SwiftUI | |
extension View { | |
func confirmationDialog(presented: Binding<Bool>, title: String, message: String? = nil, buttons: [DialogButton], horizontalSizeClass: UserInterfaceSizeClass?, onDismiss: @escaping () -> Void) -> some View { | |
self.modifier(ConfirmationDialog(isPresented: presented, | |
title: title, | |
message: message, | |
buttons: buttons, | |
horizontalSizeClass: horizontalSizeClass, | |
onDismiss: onDismiss)) | |
} | |
func `if`<Content: View>(_ conditional: Bool, content: (Self) -> Content) -> some View { | |
if conditional { | |
return AnyView(content(self)) | |
} else { | |
return AnyView(self) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment