Как вы помещаете форму в модал SwiftUI? - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь создать модал, содержащий форму в SwiftUI. Я предпочел бы не использовать листы действий в пользу модальной модели, подобной изображенной ниже. Кажется, что модалы и оповещения SwiftUI еще не способны к таким модалам, есть ли возможное решение?

enter image description here

Ответы [ 2 ]

1 голос
/ 06 марта 2020
import SwiftUI

struct ContentView: View {
    @State var flag = false
    var body: some View {
        ZStack {
            VStack {
                Text("Title").font(.largeTitle)
                Toggle(isOn: $flag) {
                    Text("Show Moda' on")
                }.padding(100)
                Spacer()
            }.disabled(flag)

            if flag {
                Color.gray.opacity(0.4).edgesIgnoringSafeArea(.all)
                VStack {
                    Text("label")
                    Button(action: {
                        self.flag.toggle()
                    }) {
                        Text("Close")
                    }
                }
                .frame(width: 300, height: 200, alignment: .center)
                .background(Color.primary.colorInvert()).cornerRadius(50)

            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

enter image description here

1 голос
/ 06 марта 2020

Два подхода

Вот два примера способов создать пользовательский модал.


1. С .overlay()

import SwiftUI

struct ContentView: View { // your main view
    @State var showModal: Bool = false

    var body: some View {
        NavigationView {
            Button(action: {
                self.showModal.toggle()
            }) {
                HStack {
                    Image(systemName: "plus.circle.fill")
                        .imageScale(.large)
                    Text("Show Modal")
                }
            }
            .navigationBarTitle("Welcome")
        }
        .navigationViewStyle(StackNavigationViewStyle())
        .overlay(ModalView(showModal: $showModal))
    }
}

struct ModalView: View { // draws a semi-transparent rectangle that contains the modal
    @Binding var showModal: Bool

    var body: some View {
        Group {
            if showModal {
                Rectangle()
                    .foregroundColor(Color.black.opacity(0.5))
                    .edgesIgnoringSafeArea(.all)
                    .overlay(
                        GeometryReader { geometry in
                            RoundedRectangle(cornerRadius: 16)
                                .foregroundColor(.white)
                                .frame(width: min(geometry.size.width - 100, 300), height: min(geometry.size.height - 100, 200))
                                .overlay(ModalContentView(showModal: self.$showModal))
                        }
                )
            }
        }
    }
}

struct ModalContentView: View { // the real modal content
    @Binding var showModal: Bool

    var body: some View {
        VStack {
            Text("Modal Content")

            Button(action: {
                self.showModal.toggle()
            }) {
                HStack {
                    Image(systemName: "xmark.circle.fill")
                        .imageScale(.large)
                    Text("Close Modal")
                }
            }
        }
    }
}


2. С ZStack

struct ContentView: View {
    @State var showModal: Bool = false

    var body: some View {
        NavigationView {
            ZStack {
                Button(action: {
                    withAnimation {
                        self.showModal.toggle()
                    }
                }) {
                    HStack {
                        Image(systemName: "plus.circle.fill")
                            .imageScale(.large)
                        Text("Show Modal")
                    }
                }

                if showModal {
                    Rectangle() // the semi-transparent overlay
                        .foregroundColor(Color.black.opacity(0.5))
                        .edgesIgnoringSafeArea(.all)

                    GeometryReader { geometry in // the modal container
                        RoundedRectangle(cornerRadius: 16)
                            .foregroundColor(.white)
                            .frame(width: min(geometry.size.width - 100, 300), height: min(geometry.size.height - 100, 200))
                            .overlay(ModalContentView(showModal: self.$showModal))
                    }
                    .transition(.move(edge: .bottom))

                }
            }
            .navigationBarTitle("Welcome")

        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

struct ModalContentView: View {
    @Binding var showModal: Bool

    var body: some View {
        VStack {
            Text("Modal Content")

            Button(action: {
                withAnimation {
                    self.showModal.toggle()
                }
            }) {
                HStack {
                    Image(systemName: "xmark.circle.fill")
                        .imageScale(.large)
                    Text("Close Modal")
                }
            }
        }
    }
}

Может быть, этот второй подход еще лучше. С этим я также получил анимацию своего рода работы.

...