SwiftUI Mac Catalyst Scrolling not working with StackNavigationViewStyle - macos

I have the following problem and I hope someone can help me out...
As soon as I use .navigationViewStyle(StackNavigationViewStyle()) the Mac Catalyst App does only scroll for a little while in the "Detailview"
Here my examplecode:
Listview:
struct Liste: View {
var body: some View {
NavigationView {
List {
NavigationLink(destination: DetailView()) {
Text("Hello World")
}
NavigationLink(destination: DetailView()) {
Text("Hello World")
}
NavigationLink(destination: DetailView()) {
Text("Hello World")
}
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
Detailview:
struct DetailView: View {
var body: some View {
VStack{
Form{
Section{
Text("Hello, World!")
}
}
}
}
}
In the following video, you can see what happens:
Any ideas what I'm doing wrong? Many thanks!

Related

.navigationBarTitleDisplayMode(.inline) crashes Xcode preview

I am consistently coming across this issue whenever I use .navigationBarTitleDisplayMode(.inline). Is there a problematic use of this method, or is there something incorrect about my code ?
How to reproduce error:
In the preview, hit the "list.bullet.rectangle.fill" and dismiss the dialog. Do it a second time and now Xcode crashes the Preview.
Xcode Version 14.2 (14C18)
import SwiftUI
struct PDFTableContentsView: View {
var body: some View {
Text("PDF Table Contents View")
.bold()
.underline()
}
}
struct PDFContentView: View {
#State private var showContents: Bool = false
var body: some View {
VStack {
Text(/*#START_MENU_TOKEN#*/"Hello, World!"/*#END_MENU_TOKEN#*/)
}
.navigationTitle("PDF Title")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
showContents.toggle()
} label: {
Image(systemName: "list.bullet.rectangle.fill")
}
}
}
.sheet(isPresented: $showContents) {
PDFTableContentsView()
}
}
}
struct PDFContentView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
PDFContentView()
}
}
}

Change size of Navigation Bar in SwiftUI

Hello SO community 👋🏼
I'm trying to recreate NavigationBar from Contact tab Apple's Phone in my SwiftUI app.
I played around with .toolbar and modifications but really can't recreate it. I wanna replace TextField to SegmentPicker with saving all behavior of .navigationBarTitleDisplayMode(.inline). But don't know is it possible to use SwiftUI only to get it or need to dive into UIKit. I'm not the expert of UIKit and I will be glad for any help. I want use this NavBar in a exact screen in the app and if possible do not change my preferences of NavBar on other part of app. My code:
import SwiftUI
struct NavBar: View {
#State var pickerOptions: Int = 0
var body: some View {
NavigationView {
ScrollView(.vertical) {
VStack {
Text("Hello, World!")
}
}
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .principal) {
SegmentPicker
}
ToolbarItem(placement: .navigationBarTrailing) {
Image(systemName: "plus")
}
ToolbarItem(placement: .navigationBarLeading) {
Text("Groups")
}
}
}
}
private var SegmentPicker: some View {
VStack {
Text("Contacts").font(.body.weight(.semibold))
Picker("Options", selection: $pickerOptions) {
Text("Cons").tag(0)
Text("Prons").tag(1)
}
.pickerStyle(.segmented)
.frame(width: 200)
}
}
}

SwiftUI macOS right sidebar inspector

I have a document-based SwiftUI app. I'd like to make a inspector sidebar like the one in Xcode.
Starting with Xcode's Document App template, I tried the following:
struct ContentView: View {
#Binding var document: DocumentTestDocument
#State var showInspector = true
var body: some View {
HSplitView {
TextEditor(text: $document.text)
if showInspector {
Text("Inspector")
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
.toolbar {
Button(action: { showInspector.toggle() }) {
Label("Toggle Inspector", systemImage: "sidebar.right")
}
}
}
}
Which yielded:
How can I extend the right sidebar to full height like in Xcode?
NavigationView works for left-side sidebars, but I'm not sure how to do it for right-side sidebars.
Here is some stripped down code that I have used in the past. It has the look and feel that you want.
It uses a NavigationView with .navigationViewStyle(.columns) with essentially three panes. Also, the HiddenTitleBarWindowStyle() is important.
The first (navigation) pane is never given any width because the second (Detail) pane is always given all of the width when there is no Inspector, or all of the width less the Inspector's width when it's present. The ToolBar needs to be broken up and have its contents placed differently depending on whether the Inspector is present or not.
#main
struct DocumentTestDocumentApp: App {
var body: some Scene {
DocumentGroup(newDocument: DocumentTestDocument()) { file in
ContentView(document: file.$document)
}
.windowStyle(HiddenTitleBarWindowStyle())
}
}
struct ContentView: View {
#Binding var document: DocumentTestDocument
#State var showInspector = true
var body: some View {
GeometryReader { window in
if showInspector {
NavigationView {
TextEditor(text: $document.text)
.frame(minWidth: showInspector ? window.size.width - 200.0 : window.size.width)
.toolbar {
LeftToolBarItems(showInspector: $showInspector)
}
Inspector()
.toolbar {
RightToolBarItems(showInspector: $showInspector)
}
}
.navigationViewStyle(.columns)
} else {
NavigationView {
TextEditor(text: $document.text)
.frame(width: window.size.width)
.toolbar {
LeftToolBarItems(showInspector: $showInspector)
RightToolBarItems(showInspector: $showInspector)
}
}
.navigationViewStyle(.columns)
}
}
}
}
struct LeftToolBarItems: ToolbarContent {
#Binding var showInspector: Bool
var body: some ToolbarContent {
ToolbarItem(content: { Text("test left toolbar stuff") } )
}
}
struct RightToolBarItems: ToolbarContent {
#Binding var showInspector: Bool
var body: some ToolbarContent {
ToolbarItem(content: { Spacer() } )
ToolbarItem(placement: .primaryAction) {
Button(action: { showInspector.toggle() }) {
Label("Toggle Inspector", systemImage: "sidebar.right")
}
}
}
}
struct Inspector: View {
var body: some View {
VStack {
Text("Inspector Top")
Spacer()
Text("Bottom")
}
}
}

SwiftUI: Perpetual Diagnostic Error When Building NavigationBar

I'm new to SwiftUI, and I'm trying to build this nav bar using Xcode 12.4:
Here is the entirety of my view:
struct PreferencesView: View {
var body: some View {
NavigationView {
ZStack {
//Background Color
Color("DosDark")
.edgesIgnoringSafeArea(.all)
Text("Hey.")
//Nav bar styles
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .principal) {
VStack {
Text("Preferences")
.navBarTitleDark()
}
}
}
.navigationBarItems(
leading: NavClose(), //<-- This is where the trouble starts
trailing: NavAbout()
)
}
}
}
}
struct NavClose: View {
var body: some View { //<-- Inexplicable error here
Button(action: {
print("Close...")
}){
Image("close-blue")
}
}
}
struct NavAbout: View {
var body: some View {
Button(action: {
print("Show about stuff...")
}) {
Image("about-blue")
}
}
}
I can get the title to render okay, but as soon as I add the .navigationBarItems bit, I see an error endlessly on my struct that I'm trying to pull in:
When I try putting the Button directly in .navigationBarItems (without using an external struct) I still see the error on that line:
Failed to produce diagnostic for expression; please file a bug report
Am I doing something wrong? Is there a way to make Xcode give me a real error message?
Works fine with Xcode 12.1 / iOS 14.1, but .navigationBarItems was deprecated for the preference of toolbar and probably you have newer version where they are already conflicted.
The solution is to use only toolbar with corresponding placements, like
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
NavClose()
}
ToolbarItem(placement: .navigationBarTrailing) {
NavAbout()
}
ToolbarItem(placement: .principal) {
VStack {
Text("Preferences")
.navBarTitleDark()
}
}
}

Simulate button click in macOS SwiftUI?

I’ve built a simple macOS modal dialog in SwiftUI that takes some text from the user:
struct
OpenLocationView : View
{
#State private var location: String = ""
var body: some View
{
VStack
{
HStack
{
Text("Location:")
TextField("https://", text: $location) { self.openLocation() }
}
HStack
{
Spacer()
Button("Cancel") { self.dismiss() }
Button("Open") { self.simulateClick() }
}
}
.padding()
.frame(minWidth: 500.0)
}
}
If the user presses enter or return, I’d like to briefly simulate a click on the default button before dismissing the dialog. How would I do this in SwiftUI?
Actually you've almost done it, see comments inline
...
HStack
{
Text("Location:")
TextField("https://", text: $location) {
// this is onCommit: called on Return or Enter
self.open()
}
}
HStack
{
Spacer()
Button("Cancel") { self.dismiss() }
Button("Open") { self.open() }
}
...
func open() {
self.openLocation()
self.dismiss()
}

Resources