| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import Combine
- import SwiftUI
- struct RoundedBackground: ViewModifier {
- private let color: Color
- init(color: Color = Color("CapsuleColor")) {
- self.color = color
- }
- func body(content: Content) -> some View {
- content
- .padding()
- .background(
- RoundedRectangle(cornerRadius: 8, style: .continuous)
- .fill()
- .foregroundColor(color)
- )
- }
- }
- struct CapsulaBackground: ViewModifier {
- private let color: Color
- init(color: Color = Color("CapsuleColor")) {
- self.color = color
- }
- func body(content: Content) -> some View {
- content
- .padding()
- .background(
- Capsule()
- .fill()
- .foregroundColor(color)
- )
- }
- }
- struct Link<T>: ViewModifier where T: View {
- private let destination: T
- init(destination: T) {
- self.destination = destination
- }
- func body(content: Content) -> some View {
- ZStack {
- NavigationLink(destination: destination) {
- EmptyView()
- }.hidden()
- content
- }
- }
- }
- struct AdaptsToSoftwareKeyboard: ViewModifier {
- @State var currentHeight: CGFloat = 0
- func body(content: Content) -> some View {
- content
- .padding(.bottom, currentHeight).animation(.easeOut(duration: 0.25))
- .edgesIgnoringSafeArea(currentHeight == 0 ? Edge.Set() : .bottom)
- .onAppear(perform: subscribeToKeyboardChanges)
- }
- private let keyboardHeightOnOpening = NotificationCenter.default
- .publisher(for: UIResponder.keyboardWillShowNotification)
- .map { $0.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! CGRect }
- .map(\.height)
- private let keyboardHeightOnHiding = NotificationCenter.default
- .publisher(for: UIResponder.keyboardWillHideNotification)
- .map { _ in CGFloat(0) }
- private func subscribeToKeyboardChanges() {
- _ = Publishers.Merge(keyboardHeightOnOpening, keyboardHeightOnHiding)
- .subscribe(on: DispatchQueue.main)
- .sink { height in
- if self.currentHeight == 0 || height == 0 {
- self.currentHeight = height
- }
- }
- }
- }
- extension View {
- func roundedBackground() -> some View {
- modifier(RoundedBackground())
- }
- func buttonBackground() -> some View {
- modifier(RoundedBackground(color: .accentColor))
- }
- func navigationLink<V: BaseView>(to screen: Screen, from view: V) -> some View {
- modifier(Link(destination: view.viewModel.view(for: screen)))
- }
- func adaptsToSoftwareKeyboard() -> some View {
- modifier(AdaptsToSoftwareKeyboard())
- }
- func modal<V: BaseView>(for screen: Screen?, from view: V) -> some View {
- onTapGesture {
- view.viewModel.showModal(for: screen)
- }
- }
- func asAny() -> AnyView { .init(self) }
- }
|