Skip to content

Commit

Permalink
The alert did not go away after closing. Always use the same implemen…
Browse files Browse the repository at this point in the history
…tation on all the iOS versions
  • Loading branch information
laevandus committed May 24, 2024
1 parent af5c7e3 commit 91a2702
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,28 +177,16 @@ struct SuggestOptionModifier: ViewModifier {
var submit: () -> Void

func body(content: Content) -> some View {
if #available(iOS 15.0, *) {
content
.alert(title, isPresented: $showingAlert) {
TextField(L10n.Alert.TextField.pollsNewOption, text: $text)
Button(L10n.Alert.Actions.cancel, role: .cancel) {
showingAlert = false
}
Button(L10n.Alert.Actions.add, action: submit)
} message: {
Text("")
}
} else {
content
.uiAlertController(
title: title,
isPresented: $showingAlert,
text: $text,
textPlaceholder: L10n.Alert.TextField.pollsNewOption,
cancelActionTitle: L10n.Alert.Actions.cancel,
defaultActionTitle: L10n.Alert.Actions.add
)
}
content
.uiAlert(
title: title,
isPresented: $showingAlert,
text: $text,
placeholder: L10n.Alert.TextField.pollsNewOption,
cancel: L10n.Alert.Actions.cancel,
accept: L10n.Alert.Actions.add,
action: submit
)
}
}

Expand Down
104 changes: 55 additions & 49 deletions Sources/StreamChatSwiftUI/Utils/SwiftUI+UIAlertController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,32 @@

import SwiftUI

@available(iOS, deprecated: 15.0, message: "Use .alert()")
extension View {
/// Presents an alert with a text field for entering text.
///
/// - Note: Only for iOS 14 which lacks text field support.
func uiAlertController(
/// - Note: iOS 14 lacks alert with text field support.
func uiAlert(
title: String,
isPresented: Binding<Bool>,
message: String = "",
text: Binding<String>,
textPlaceholder: String,
cancelActionTitle: String,
defaultActionTitle: String
placeholder: String,
cancel: String,
accept: String,
action: @escaping () -> Void
) -> some View {
ZStack {
if isPresented.wrappedValue {
UIAlertControllerView(
isPresented: isPresented,
title: title,
message: message,
text: text,
textPlaceholder: textPlaceholder,
cancelActionTitle: cancelActionTitle,
defaultActionTitle: defaultActionTitle
)
}
UIAlertControllerView(
isPresented: isPresented,
title: title,
message: message,
text: text,
placeholder: placeholder,
cancel: cancel,
accept: accept,
action: action
)
.frame(height: 0)
self
}
}
Expand All @@ -40,56 +40,62 @@ private struct UIAlertControllerView: UIViewControllerRepresentable {
let title: String
let message: String
@Binding var text: String
let textPlaceholder: String

let cancelActionTitle: String
let defaultActionTitle: String
let placeholder: String
let cancel: String
let accept: String
let action: () -> Void

func makeUIViewController(context: Context) -> UIViewController {
UIViewController()
}

func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
guard isPresented else { return }
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addTextField { textField in
textField.delegate = context.coordinator
textField.font = .preferredFont(forTextStyle: .body)
textField.placeholder = textPlaceholder
textField.text = text
}
alert.addAction(
UIAlertAction(title: cancelActionTitle, style: .cancel) { _ in
isPresented = false
if isPresented && uiViewController.presentedViewController == nil {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
context.coordinator.alertController = alert
alert.addTextField { textField in
textField.font = .preferredFont(forTextStyle: .body)
textField.placeholder = placeholder
textField.text = text
}
)
alert.addAction(
UIAlertAction(title: defaultActionTitle, style: .default) { _ in
isPresented = false
alert.addAction(
UIAlertAction(title: cancel, style: .cancel) { _ in
isPresented = false
}
)
let textField = alert.textFields?.first
alert.addAction(
UIAlertAction(title: accept, style: .default) { _ in
text = textField?.text ?? ""
isPresented = false
action()
}
)
DispatchQueue.main.async {
uiViewController.present(alert, animated: true)
}
)
DispatchQueue.main.async {
uiViewController.present(alert, animated: true)
}
if !isPresented {
context.coordinator.alertController?.dismiss(animated: true)
}
}

static func dismantleUIViewController(_ uiViewController: UIViewController, coordinator: Coordinator) {
coordinator.alertController?.dismiss(animated: true)
coordinator.alertController = nil
}

func makeCoordinator() -> Coordinator {
Coordinator { text in
self.text = text
}
Coordinator()
}
}

private extension UIAlertControllerView {
final class Coordinator: NSObject, UITextFieldDelegate {
let didChangeSelection: (String) -> Void

init(didChangeSelection: @escaping (String) -> Void) {
self.didChangeSelection = didChangeSelection
}
var alertController: UIAlertController?

func textFieldDidChangeSelection(_ textField: UITextField) {
didChangeSelection(textField.text ?? "")
init(alertController: UIAlertController? = nil) {
self.alertController = alertController
}
}
}

0 comments on commit 91a2702

Please sign in to comment.