SwiftUI .fullScreenCover appears as a .sheet - swiftui

I expected to be able to dismiss a sheet and present a fullScreenCover straight after, however this doesn't seem to work without a delay between the two state modifications.
struct ContentView: View {
#State var sheet = false
#State var cover = false
var body: some View {
Button("Click me for sheet") {
sheet = true
}
.fullScreenCover(isPresented: $cover) {
Text("This is a full screen cover")
}
.sheet(isPresented: $sheet) {
Text("This is a sheet")
Button("This doesn't work") {
sheet = false
cover = true
}
Button("This works") {
sheet = false
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
cover = true
}
}
}
}
}
Clicking the "This doesn't work" button produces the below image demonstrating a fullScreen cover displaying as a sheet and not covering the entire screen:
Introducing a small delay between the two state modifications which is done by clicking the "This works" button fixes the issue.
What am I not understanding about SwiftUI here that would explain this behaviour?
Tested on:
Xcode 12.5.1
iPhone 12 Pro Max Simulator running iOS 14.5
Adding the modifiers to seperate view like this also doesn't work:
Text("Another view").sheet(isPresented: $sheet) { ...

you could try this:
struct ContentView: View {
#State var sheet = false
#State var cover = false
var body: some View {
Button("Click me for sheet") {
sheet = true
}
.fullScreenCover(isPresented: $cover) {
Text("This is a full screen cover")
}
.sheet(isPresented: $sheet, onDismiss: {cover = true}) {
Text("This is a sheet")
}
}
}

Related

Why popover fullscreen in swiftUI?

I am using popover. But popover shows fullscreen iphone.
Here is the image
Here is the code:
Popover action:
#State private var showPopover = false
var body: some View {
Button(action: {
self.showPopover = true
}) {
Text("Show Popover")
}
.popover(isPresented: $showPopover) {
PopoverView()
}
}
Here is popover:
struct PopoverView: View {
#State var adaptableHeight = CGFloat(100)
var body: some View {
VStack {
Text("Popover Content")
Button("Dismiss") {
// dismiss the popover
}
}
}
}
Is there any project configuration issue?
what is wrong with the code...
Currently you should use your own struct to use a popover on iPhone, if you run your code on an iPad you should see the popover you’re looking for. Hopefully Apple will fix that soon.

TextField in sheet that accepts focus immediately without any noticeable delay

I want to open a Sheet in SwiftUI that 1) contains a TextField which 2) accepts focus immediately. Unfortunately, as demonstrated in the attached clip, there’s a short but noticeable delay before the keyboard pops up. This makes the transition into the focused state not as smooth as I would like (UI shifting to make room for the keyboard).
Minimum reproducible example:
struct TestRootView: View {
#State private var sheet = false
var body: some View {
Button("Open sheet") {
sheet.toggle()
}
.sheet(isPresented: $sheet) {
SheetView()
}
}
}
struct SheetView: View {
#Environment(\.dismiss) var dismiss
#FocusState var isFocused
#State var text: String = ""
var body: some View {
TextField("title", text: $text)
.focused($isFocused)
.onAppear {
isFocused = true
}
Button("Close") {
dismiss()
}.font(.title)
.padding()
.background(.black)
}
}

SwiftUI : how to make this raising up view

I am just curious for this animation, when i click one button, the origin page will fall down a bit and the new page will raise up with a cross button on top left corner.
Seems it's quite a common behavior, anyone who know is there any official api for this animation ?
This is just two sheets presented, one on top of the other.
Example code:
struct ContentView: View {
#State private var isPresented = false
var body: some View {
VStack {
Text("Content")
Button("Present sheet") {
isPresented = true
}
.sheet(isPresented: $isPresented) {
MainSheet()
}
}
}
}
struct MainSheet: View {
#State private var isPresented = false
var body: some View {
VStack {
Text("Sheet content")
Button("Present another sheet") {
isPresented = true
}
.sheet(isPresented: $isPresented) {
Text("Final content")
}
}
}
}
Result:

Popover in the navigation bar results in broken animation

When I have a popover in the navigation bar the animation is broken when closing the popover. Also it can only be opened once. It works fine on the iPad, but the animation is different on the iPad. Is this a bug?
struct ContentView: View {
#State var showPopover:Bool = false
var body: some View {
NavigationView{
Text("Popover Animation Test")
.navigationBarItems(trailing: Button("Popover") { self.showPopover = true }
.popover(isPresented: self.$showPopover) { Text("Hello from Popover") })
}
}
}

Using SwiftUI, we installed a Button in the List. Why does the modal disappear when I tap the button to display the modal and then close it again?

I am now learning to create a sample code for SwiftUI using the official version of Xcode11.
I wrote a simple code to show and hide modal.
This code adds a button to the list and displays a modal.
Strangely, however, the modal no longer appears when the button is tapped again after closing.
Is there a reason for this or any solution?
Occurs when there is a button in the list, but if you delete only the list from the code, the modal can be displayed as many times as you like.
This is the code that causes the bug.
struct ContentView: View {
#State var show_modal = false
var body: some View {
List {
Button(action: {
print("Button Pushed")
self.show_modal = true
}) {
Text("Show Modal")
}.sheet(isPresented: self.$show_modal, onDismiss: {
print("dismiss")
}) {
ModalView()
}
}
}
}
This is a code that does not cause a bug.
struct ContentView: View {
#State var show_modal = false
var body: some View {
Button(action: {
print("Button Pushed")
self.show_modal = true
}) {
Text("Show Modal")
}.sheet(isPresented: self.$show_modal, onDismiss: {
print("dismiss")
}) {
ModalView()
}
}
}
The only difference is whether or not there is a List.
The ModalView code is below.
struct ModalView: View {
// 1. Add the environment variable
#Environment(\.presentationMode) var presentationMode
var body: some View {
// 2. Embed Text in a VStack
VStack {
// 3. Add a button with the following action
Button(action: {
print("dismisses form")
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Dismiss")
}.padding(.bottom, 50)
Text("This is a modal")
}
}
}
When breakpoint is set, print ("Button Pushed") is called every time, but ModalView of .sheet is not called, and naturally the body of ModalView class is not called.
I think the issue is that your .sheet is not on the List itself but on the Button in your code that causes the bug.
Try this instead:
struct ContentView: View {
#State var show_modal = false
var body: some View {
List {
Button(action: {
print("Button Pushed")
self.show_modal = true
}) {
Text("Show Modal")
}
}.sheet(isPresented: self.$show_modal, onDismiss: {
print("dismiss")
}) {
ModalView()
}
}
}