When I embed my view's body inside of a NavigationView I lose all ability to select subviews within the preview window, as well as the reverse ability of selecting code to trigger and display the blue border around the associated subview in the preview. It only shows a blue border around the entire NavigationView no matter what or where I click. Is this a bug? If not, what am I doing wrong?
Edit: Per the request of the comments below, here is a simple example:
struct FooView: View {
var body: some View {
NavigationView {
VStack {
Label("Try")
Label("Selecting")
Label("These")
}
}
}
}
Related
In SwiftUI I currently have a VStack of views, and I'd like to put an overlay over the bottom two views, like this:
VStack {
Spacer()
Group {
centerView
Spacer()
}
.overlay(overlayedView)
}
The goal of the above layout is ensure that centerView is vertically centered, while also ensuring that the overlayedView goes from the top of centerView all the way to the bottom of the VStack.
However, the above code actually results in one instance of overlayedView getting overlayed on top of centerView and another overlayedView getting overlayed on top of the bottom Spacer. But what I want is a single overlayedView spread on top of both centerView and the bottom Spacer.
How can I achieve my desired behavior?
Using Group will add view modifiers to all the subviews of the group, resulting in 2 seperate overlays. To have one common overlay, you can use VStack instead of Group.
VStack {
Spacer()
VStack {
centerView
Spacer()
}
.overlay(overlayedView)
}
Have a simple NavigationView with fixed content on both sides. The left pane just shows a couple of buttons and the right pane shows a graph using an NSView wrapped in an NSViewRepresentable. When viewing on iPad in portrait mode, the left pane disappears as expected but the 'back' button does not show. Can click in the area where the 'back' button was expected and the left pane shows up. There just isn't anything visible there.
What am I doing wrong?
var body: some View {
NavigationView {
VStack(alignment: .center) {
Text("This is the left side")
Button {
...
} label: {
Text("Create Estimate")
}.foregroundColor(Color.black)
Button {
...
} label: {
Text("Reset Results")
}.foregroundColor(Color.black)
Text("This is the end of the left side")
}
VStack {
Text("This is the right side")
AreaChartView(redrawCount: redrawCounter, scenario: activeScenario)
}
}
}
}
Update: This happens even when I comment out everything in the NavigationView above and replace with:
NavigationView {
Text("This is the left side")
Text("This is the right side")
}
Note that I created a new iOS project with nothing but this super-simple NavigationView and it shows the Back button just as expected. Since literally everything in my app's view except the NavigationView above is commented out, I'm wondering what else may be wrong in the environment. Note that my app is a multi-platform app rather than just iOS, though I don't know why that would matter.
OK - for any other poor soul who may encounter this...
When I found that even a trivial NavigationView had no 'Back' button (see question), it became clear that the trouble was not in the view code at all. Took some searching but discovered that somehow the default accent colors in the Assets file had been changed to white. This meant that the 'Back' button was white against a white background and was thus invisible.
Deleting these white accent colors causes SwiftUI to use defaults. Now the 'Back' button shows in blue as expected.
When using a Form on a view and presenting it with either .sheet or .fullScreenCover the view is never presented and instead memory is quickly gobbled until the app crashes. Removing the form and replacing it with anything else works just fine.
Inside top level view, the sheet or full screen uses:
.fullScreenCover(isPresented: $showProfile, content: {
NavigationView {
ProfileNumberView()
}
})
OR
.sheet(isPresented: $showProfile, content: {
NavigationView {
ProfileNumberView()
}
})
The view it's launching can be as simple as:
var body: some View {
Form {
Text("TEST")
}
}
Again doing this causes the app to simply gobble up memory until a crash and no view is presented. If I simply remove the Form tag, the the view will present as normal. I have also tried embedding the NavigationView inside the form view (above the Form tag) but to no avail.
Why can I not present a view using a Form in this manner?
Update: I have discovered the source of the issue is when the top level view contains a List. If there is no list the screens present just fine, but it seems we cannot present a form within a cover or sheet if the parent has a list in it. Still not clear why that would be the case but commenting out the list and the sheet or fullscreencover worked.
The turned out to be something that was not directly related to the code I posted above. It's worth posting the answer though as I am sure others may run into this. The problem was styling given to the list in order to paint a background with an image. Specifically:
UITableViewCell.appearance().backgroundColor = .clear
let imageView = UIImageView(image: UIImage(named: "gradientBackground"))
imageView.contentMode = .scaleToFill
UITableView.appearance().backgroundView = imageView
This styling of the list for some reason prevents you from presenting a sheet or full screen cover that has a form. Very unclear why and I need this background, so while this particular issue is resolved, the functionality required is not.
I would like the NavigationBar (from a SwiftUI NavigationView) to just stay large and scroll out whenever I scroll in a Pages ScrollView. Right now it is always collapsing and showing even on scroll in ".inline"-display mode. So when I try to completely hide it I also hide the large title I'd like to keep.
Is there a way to just let it stay large and just scroll out?
Any solution in SwiftUI or UIKit is appreciated as I can introspect from UIKit.
I especially don't want the NavigationBar to be hidden and rebuild by VStack or HStack as this causes loosing all Navigation Gestures like swiping back to the previous Navigation View and so...
Here is a basic codesnipped to recreate
struct TestTestView: View {
var body: some View {
NavigationView {
ScrollView() {
Color.green
.frame(height: 1000)
}
.navigationTitle("Test")
}
}
}
I'm trying to make navigation view that leads to destination view with scroll view, where navigation title of destination view would animate towards inline display mode or at least scroll behind the nav bar itself.
Basically I'm trying to replicate behavior of standard Music app, specifically when you go from Library to Songs.
There you have source view (Library) with its own title that is animated into inline display mode on scroll. When you tap Songs you also get list with new title (Songs) that also animates into inline display mode on scroll.
So I have main NavigationView with NavigationBarTitle. I move to destinationView with its own NavigationBarTitle and some long list of content. On scroll, NavigationBarTitle of main Navigation view changes to inline display mode, but NavigationBar of destination view behaves very odd: it's basically an overlay with no background and no animation.
And if you remove NavigationBarTitle of destination view all together it only makes things worse. It seems like it adds another transparent NavigationBar with nothing in it.
Also tried to add background to the navigation bar, looked around documentation, but found no solution.
Not sure if I'm doing something very wrong or it's just beta bug of SwiftUI or Xcode.
import UIKit
struct ContentView: View {
var body: some View {
NavigationView{
List(0..<20) { item in
NavigationLink(destination: DetailedView()) {
Text("Next view")
}
}
.navigationBarTitle("Source View")
}
}
}
struct DetailedView: View {
var body: some View {
List(0...25) { number in
Text("This is \(number)'th row")
}
.navigationBarTitle(Text("Destination View"))
// comment out line above to see empty frame of navigation bar
}
}
This is not a full answer to your question, but a temporary workaround: add top or vertical padding to your list on the child view, depending on your preference. This is what I have been doing until there is a better solution.
This will at least make the content scroll under the navigation header with a proper background rendered behind the header. It doesn't have the nice animation to make the title smaller.
struct DetailedView: View {
var body: some View {
List(0...25) { number in
Text("This is \(number)'th row")
}
.padding(.top)
.navigationBarTitle(Text("Destination View"))
}
}
This is fixed in the iOS 13.1 public release (with the App Store release of Xcode 11).
I'm currently on beta 5, and I think this is an ongoing bug with SwiftUI.
I noticed the same issue while doing the SwiftUI Landmarks Tutorials, and you can easily reproduce the issue: https://imgur.com/a/aYgUUH0
For now, to avoid seeing all the content scroll under a transparent navBar, I've converted all of my Navbars to display as inline, since automatic and large experience the issue.
List {
// ...
}
.navigationBarTitle(Text("MyTitle"), displayMode: .inline)