Popover in the navigation bar results in broken animation - swiftui

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

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.

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

SwiftUI .popover dismiss won't work after List row being removed

I have a SwiftUI List with rows that contain a thumb. When clicked, this thumb opens a popover with a larger version of the image.
The problem I'm facing is that when a row, with its popover open, is removed from the list, the popover is left open and with no way of closing it, ending up with an unusable UI.
My goal would be to have the popover closed automatically when the row is removed from the list.
Following is a stripped version of the row's body. I'm using a Button because is more reliable than the onTapGesture event.
#State private var showPopover: Bool = false
var body: some View {
Button(action: { self.showPopover = true }) {
Image(systemName: "photo")
.onDisappear { self.showPopover = false}
}
.popover(isPresented: $showPopover, arrowEdge: .leading) {
Image(systemName: "photo")
}
}
You use this:
for dismiss, swipe down or tap on Back button! (I guarantee it is going dismiss)100%
import SwiftUI
struct ContentView: View {
#State private var showModalView: Bool = false
var body: some View {
VStack
{
Button("showModalView") {showModalView.toggle()}
}
.sheet(isPresented: $showModalView, content: {
ZStack
{
Color.red
.ignoresSafeArea()
Button("← Back"){showModalView.toggle()}.foregroundColor(Color.black)
}
})
}
}

SwiftUI weird animation when showing popover on iPhone

If I show a popover in SwiftUI on the iPhone, and dismiss by swiping down the popover, the dismiss animation is incorrect.
This happens with Xcode 12.0.1, on iOS 14.0.1.
struct MyPopover: View {
var body: some View {
VStack {
Spacer()
Button("Show alert") {
// blah
}
Spacer()
}
.frame(maxWidth: .infinity)
.background(Color.green.edgesIgnoringSafeArea(.all))
}
}
struct ContentView: View {
#State private var isShowingPopover = false
var body: some View {
Button("Tap me to show a popover!") {
self.isShowingPopover.toggle()
}
.popover(isPresented: self.$isShowingPopover) {
MyPopover()
}
}
}
This is the result:
The "fix" is to use .sheet() on iPhone, but is there a reason why this behavior exists?

SwiftUI: Back button disappears when clicked on NavigationLink

I'm trying to add a NavigationLink at the top of the screen, but once I click it, it prompts me to the result and the Back button disappears.
SwiftUI Code:
NavigationView {
VStack {
NavigationLink (destination: Text("COOL")) {
Text("COOL")
}
Spacer()
}
.navigationBarHidden(true)
.navigationBarTitle(Text("Home"))
//.edgesIgnoringSafeArea([.top, .bottom])
}
The back button disappears after clicking on the NavigationLink: https://gyazo.com/9d39936c849f570a05687e41096ddeca
There is some glitch IMHO, when you use both .navigationBarHidden(true) and .navigationBarTitle(Text("Some text)). If you remove the last one, back button works as usual. Nevertheless I tried to return back button in your code snippet. It still has glitch while returning to first view, but back button don't disappear. I hope it will help and you will go further from here:
struct NotHiddenBackButton: View {
#State var hiddingNavBar = true
#State var goToSecondView = false
var body: some View {
NavigationView {
NavigationLink(destination: ViewWithBackButton(hiddingNavBar: $hiddingNavBar), isActive: $goToSecondView) {
VStack {
Text("COOL")
.onTapGesture {
self.hiddingNavBar = false
self.goToSecondView = true
}
Spacer()
}
}
.navigationBarHidden(hiddingNavBar)
.navigationBarTitle(Text("Home"))
}
}
}
struct ViewWithBackButton: View {
#Binding var hiddingNavBar: Bool
var body: some View {
Text("Second view")
.navigationBarTitle("Second view")
.onDisappear() {
self.hiddingNavBar = true
}
}
}
I believe this was a bug that has now been fixed in iOS 14