如何将表单放入 SwiftUI 模态?
How do you put a Form in a SwiftUI Modal?
我正在尝试在 SwiftUI 中创建一个包含表单的模式。我不想使用操作表来支持类似于下图所示的模式。似乎 SwiftUI Modals 和 Alerts 还不能使用这种模式,有没有可能的解决方案?
两种方法
这里有两个创建自定义模式的方法示例。
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")
}
}
}
}
}
也许第二种方法更好。有了这个,我也得到了动画的一种工作。
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()
}
}
我正在尝试在 SwiftUI 中创建一个包含表单的模式。我不想使用操作表来支持类似于下图所示的模式。似乎 SwiftUI Modals 和 Alerts 还不能使用这种模式,有没有可能的解决方案?
两种方法
这里有两个创建自定义模式的方法示例。
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")
}
}
}
}
}
也许第二种方法更好。有了这个,我也得到了动画的一种工作。
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()
}
}