Why popover fullscreen in swiftUI? - 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.

Related

SwiftUI .fullScreenCover appears as a .sheet

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")
}
}
}

unexpected behaviour with SwiftUI .constant(nil) binding in SheetView

I came across some issues with my SwiftUI code.
I made a simple example.
Just a Button that opens a Sheet.
struct ContentView: View {
#State private var showSheet = false
var body: some View {
Button(action: {
showSheet.toggle()
}, label: {
Text("Button")
})
.sheet(isPresented: $showSheet) {
SheetView(show: $showSheet, selectedDate: .constant(nil))
}
}
}
The Sheet has an optional Binding.
You can close it via the mark button.
However, as soon as I use an #Environment wrapper, the xmark stops working.
struct SheetView: View {
#Binding var show: Bool
#Environment(\.colorScheme) var colorScheme
#Binding var selectedDate: Date?
var body: some View {
NavigationView {
Text("Hello, \(selectedDate?.description ?? "Welt")!")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
self.show = false
}) {
Image(systemName: "xmark")
.renderingMode(.original)
.accessibilityLabel(Text("Save"))
}
}
}
}
}
}
(This seems to be due to the view constantly refreshing itself?)
In addition: This only happens on my iPhone 12 Pro Max.
In the simulator or an iPhone 11 Pro Max it is working fine.
(Don't have any other devices to test on.)
If I don't use .constant(nil) but give it a $Date, it works just fine.
If I remove the #Environment, it also works.
Am I doing something wrong here?
What is my mistake?

SwiftUI how to display popover

Since popover presentation is deprecated in SwiftUI is there any alternative to display a view in a popover (preferably with arrow)?
It is not deprecated. On iOS it looks equivalent to a sheet. But on iPadOS it looks like a popover with the arrow.
struct ContentView: View {
#State private var showPopover: Bool = false
var body: some View {
VStack {
Button("Show popover") {
self.showPopover = true
}.popover(
isPresented: self.$showPopover,
arrowEdge: .bottom
) { Text("Popover") }
}
}
}

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()
}
}
}