The Problem:
The NavigationLinks in the macOS version of the SwiftUI app don't work properly.
In my case is a MasterDetailNavigationView.
What I've tried
I have the problem running the app with the macOS simulator, and also running the archived application.
I still have the problem with a brand new project with the sample code below:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VStack(alignment: .center, spacing: 10) {
NavigationLink(destination: Text("View One")) {
Text("ONE")
}
NavigationLink(destination: Text("View Two")) {
Text("TWO")
}
Spacer()
}
Text("Hello, World!")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
How to reproduce the problem:
Copy and paste the above code in a new SwiftUI project. Enable the macOS tick the the target settings. And the run on the macOS emulator.
Versions:
macOS: 10.15.4 (19E266)
Xcode: 11.4 (11E146)
Related
When having a view inside a GeomtryReader and setting the background to a color. It ignores the vertical safe area and stretches beyond it. Only when the view is at the vertical edges.
It doesn't only happen on Preview, it happens on actual device as well.
I am not sure if this is a bug or a normal behaviour of SwiftUI if so what am I doing wrong?
I have a very simple view that you can test with as follows:
import SwiftUI
struct TestView: View {
var body: some View {
GeometryReader { reader in
Text("TEST")
.background(Color.red)
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
You can add it in a VStack and add a Spacer and you will see the same behaviour when it is at the bottom.
import SwiftUI
struct TestView: View {
var body: some View {
GeometryReader { reader in
VStack {
Spacer()
Text("TEST")
.background(Color.red)
}
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
I can clip it by adding .clipped() to the Text and it will be removed but this sounds like a work around to me.
I stepped away from SwiftUI for a while so I do not remember if this is a normal behaviour or not. I did some research but couldn't find anything related to this.
I am using XCode 14.2 (14C18) and Swift swift-driver version: 1.62.15 Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51)
I explicitely specified device name in preview provider but it is not changing the device in preview editor.
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.previewDevice(PreviewDevice(rawValue: "iPhone 11"))
}
}
Have you downloaded the iPhone 11 simulator into your project? If it's not available in the device selection, it won't display by just setting the device in code. You need to have the simulator device installed as well.
Goal: use a custom Font on SwiftUI, targeting MacOS.
Problem: On iOS, custom Font works fine in SwiftUI:
But on MacOS, it doesn't:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
.font(Font.custom("SourceCodePro-ExtraLight", size: 40))
Text("Hello, world!")
.font(Font.custom("LobsterTwo", size: 40))
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Tried: I made sure that both fonts are added to Info tab on corresponding iOS and MacOs targets:
Seems to be a problem with SwiftUI using UIFont under the hood, and a special NSFont would be needed...
Any help is much appreciated!
Solved by adding this line to the plist file, and a "." as the value
The text of destination View of NavigationLink in List won't change its foreground color when uesr change appearance.
But the desitination View of the outside one works well.
See Video in https://oss.catrefuse.com/img/sample
sample code:
struct BugView: View {
var body: some View {
NavigationStack {
VStack {
List {
NavigationLink("Link in List", destination: Text("Link in List") )
.tag(UUID())
}
Spacer()
NavigationLink("Link outside", destination: Text("Link outside") )
}
}
}
}
in macOS Ventura 13.0 beta7 / iOS 16.0 / Xcode 14.0
update: I found that it seems to be a problem with the new NavigationStack in SwiftUI 3.0, which will go away as using the old NavigationView
Problem: a view on Pad shows up with unwanted split view.
My current setup is:
Catalina OSX beta 5 +
Xcode 11 Beta 5
Here is the code I used, with a Navigation View and a Navigation Title:
import SwiftUI
struct SwiftUIView: View {
var body: some View {
NavigationView {
Text("Search")
.navigationBarTitle(Text("Search"))
}
}
}
#if DEBUG
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView()
}
}
#endif
When simulated on iPad (both physical device and preview) instead of a full screen view, I get this split screen view:
If I have just a view, with no NavigationView, I get a full screen view:
import SwiftUI
struct SwiftUIView: View {
var body: some View {
Text("Hello World!")
}
}
#if DEBUG
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView()
}
}
#endif
How can I make a NavigationView full screen (not split screen) on iPad?
Update July 2022
Using NavigationStack instead of NavigationView should display as the main view as you would expect on iPad:
NavigationStack {
Text("Hello world!")
}
*In newer versions, the navigationViewStyle modifier has been deprecated.
Original answer:
You can apply the .navigationViewStyle(.stack) modifier to the NavigationView.
...
NavigationView {
Text("Hello world!")
}
.navigationViewStyle(.stack)
...
Edit: Below, I am answering Alexandre's questions from his comment:
Why full view is not the default for iPad? That's just a choice made by Apple...
Why this modifier goes outside of NavigationView closure, while the Navigation Title goes inside... Maybe this gives clarification: https://stackoverflow.com/a/57400873/11432719
To use this split style for iPad but remove for iPhone:
extension View{
func phoneOnlyStackNavigationView() ->some View {
if UIDevice.current.userInterfaceIdiom == .phone{
return AnyView(self.navigationViewStyle(StackNavigationViewStyle()))
} else {
return AnyView(self)
}
}
}