StikDebug/StikJIT/Views/TextFieldAlert.swift

77 lines
2.4 KiB
Swift

//
// TextAlert.swift
// StikJIT
//
// Created by s s on 2025/5/11.
//
import SwiftUI
import UIKit
public struct TextFieldAlertModifier: ViewModifier {
@State private var alertController: UIAlertController?
@Binding var isPresented: Bool
let title: String
let text: Binding<String>
let placeholder: String
let action: (String?) -> Void
let actionCancel: (String?) -> Void
public func body(content: Content) -> some View {
content.onChange(of: isPresented) { isPresented in
if isPresented, alertController == nil {
let alertController = makeAlertController()
self.alertController = alertController
guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
return
}
scene.windows.first?.rootViewController?.present(alertController, animated: true)
} else if !isPresented, let alertController = alertController {
alertController.dismiss(animated: true)
self.alertController = nil
}
}
}
private func makeAlertController() -> UIAlertController {
let controller = UIAlertController(title: title, message: nil, preferredStyle: .alert)
controller.addTextField {
$0.placeholder = self.placeholder
$0.text = self.text.wrappedValue
$0.clearButtonMode = .always
}
controller.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
self.actionCancel(nil)
shutdown()
})
controller.addAction(UIAlertAction(title: "OK", style: .default) { _ in
self.action(controller.textFields?.first?.text)
shutdown()
})
return controller
}
private func shutdown() {
isPresented = false
alertController = nil
}
}
extension View {
public func textFieldAlert(
isPresented: Binding<Bool>,
title: String,
text: Binding<String>,
placeholder: String = "",
action: @escaping (String?) -> Void,
actionCancel: @escaping (String?) -> Void
) -> some View {
self.modifier(TextFieldAlertModifier(isPresented: isPresented, title: title, text: text, placeholder: placeholder, action: action, actionCancel: actionCancel))
}
}