Вы можете иметь ZStack
с видом, который отображается условно в зависимости от переменной @State
. Переменная также будет определять величину .blur
в базовом представлении и будет ли отображаться прозрачный серый вид между ними (что делает фон серым). Я сделал пример для иллюстрации:
struct ContentView: View {
@State var modalIsPresented = false
@State var alertIsPresented = false
@State var customAlertIsPresented = false
var body: some View {
ZStack {
Text("Test!!!")
VStack {
Spacer()
Text("Lorem ipsum dolor sit amet")
Spacer()
Text("Lorem ipsum dolor sit amet")
Image(systemName: "star")
Button(action: {
self.modalIsPresented = true
}) {
Text("Present an actual modal")
}
Button(action: {
self.alertIsPresented = true
}) {
Text("Present an actual alert")
}
Button(action: {
withAnimation {
self.customAlertIsPresented = true
}
}) {
Text("Present your custom alert")
}
}
.blur(radius: self.customAlertIsPresented ? 3 : 0)
.animation(.easeOut)
if customAlertIsPresented {
Rectangle()
.background(Color.black)
.opacity(0.3)
.edgesIgnoringSafeArea(.all)
.animation(.easeIn)
}
if customAlertIsPresented {
CustomAlert(isPresented: $customAlertIsPresented).frame(width: 300)
.background(Color.white)
.animation(.easeIn)
.cornerRadius(10)
.shadow(radius: 10)
}
}.sheet(isPresented: $modalIsPresented) {
Text("This is what an actual modal looks like")
}.alert(isPresented: $alertIsPresented) {
Alert(title: Text("This is what an alert looks like"))
}
}
}
struct CustomAlert: View {
@Binding var isPresented: Bool
var body: some View {
VStack {
Text("This is my custom alert").padding()
Divider()
Button(action: {
self.isPresented = false
}) {
HStack {
Spacer()
Text("Dismiss")
Spacer()
}
}.padding([.top, .bottom], 10)
}
}
}
Я добавил несколько анимаций, чтобы сделать переход более плавным. Вы можете настроить такие параметры, как .blur
, .opacity
и различные .animation
, чтобы настроить его так, как вы хотите. Вот как выглядит мой пример:

