From 8247870e1e573b4c8c68e98ee78c1d2ba4b18caf Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Fri, 16 Dec 2022 23:59:26 +0100 Subject: [PATCH] Implemented the InputAlertView component for the Browse module. --- .../Browse/UI/Components/InputAlertView.swift | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 Modules/Sources/Browse/UI/Components/InputAlertView.swift diff --git a/Modules/Sources/Browse/UI/Components/InputAlertView.swift b/Modules/Sources/Browse/UI/Components/InputAlertView.swift new file mode 100644 index 0000000..a1c1b36 --- /dev/null +++ b/Modules/Sources/Browse/UI/Components/InputAlertView.swift @@ -0,0 +1,134 @@ +// +// InputAlertView.swift +// Browse +// +// Created by Javier Cicchelli on 16/12/2022. +// Copyright © 2022 Röck+Cöde. All rights reserved. +// + +import DataModels +import SwiftUI +import UIKit + +struct InputAlertView: UIViewControllerRepresentable { + + // MARK: Bindings + + @Binding private var isPresenting: Bool + @Binding private var textFieldString: String + + // MARK: Properties + + private let title: String + private let message: String + private let textFieldPlaceholder: String + private let actions: [UIAlertAction] + + // MARK: Initialisers + + init( + isPresenting: Binding, + title: String, + message: String, + textFieldPlaceholder: String, + textFieldString: Binding, + actions: [UIAlertAction] + ) { + self.title = title + self.message = message + self.textFieldPlaceholder = textFieldPlaceholder + self.actions = actions + + self._isPresenting = isPresenting + self._textFieldString = textFieldString + } + + // MARK: Functions + + func makeUIViewController( + context: UIViewControllerRepresentableContext + ) -> UIViewController { + .init() + } + + func updateUIViewController( + _ viewController: UIViewController, + context: UIViewControllerRepresentableContext + ) { + guard + context.coordinator.alert == nil, + isPresenting + else { return } + + let alertController = { + let alert = UIAlertController( + title: title, + message: message, + preferredStyle: .alert + ) + + alert.addTextField { textField in + textField.placeholder = textFieldPlaceholder + textField.text = textFieldString + textField.delegate = context.coordinator + } + + actions.forEach { action in + alert.addAction(action) + } + + return alert + }() + + context.coordinator.alert = alertController + + Task { @MainActor in + viewController.present( + alertController, + animated: true + ) { + isPresenting = false + context.coordinator.alert = nil + } + } + } + + func makeCoordinator() -> InputAlertView.Coordinator { + Coordinator(self) + } + +} + +// MARK: - Coordinator + +extension InputAlertView { + class Coordinator: NSObject, UITextFieldDelegate { + + // MARK: Properties + + var alert: UIAlertController? + + private let component: InputAlertView + + // MARK: Initialisers + + init(_ component: InputAlertView) { + self.component = component + } + + // MARK: UITextFieldDelegate + + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + component.textFieldString = { + if let text = textField.text as NSString? { + return text.replacingCharacters(in: range, with: string) + } else { + return .empty + } + }() + + return true + } + + } +}