折叠 macOS SwiftUI 侧边栏项目

huangapple go评论69阅读模式
英文:

Collapse sidebar items on macOS SwiftUI

问题

在尝试使用SwiftUI在macOS应用程序中复制Finder和SF Symbols的行为时,我在使用DisclosureGroup时遇到了困难。

以下是我的当前代码:

import SwiftUI

struct SidebarView: View {
    @State private var companiesExpanded = false
    
    var body: some View {
        VStack{
            DisclosureGroup(isExpanded: $companiesExpanded) {
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("水", systemImage: "drop")
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("污水", systemImage: "toilet")
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("电力", systemImage: "bolt")
                }
            } label: {
                Text("公司")
                    .font(.subheadline)
                    .fontWeight(.semibold)
            }
        }
    }
}

在这段代码中,我尝试使用DisclosureGroup创建侧边栏中的可折叠部分,类似于Finder和SF Symbols中所见。然而,结果不同。DisclosureGroup确实会折叠项目,但它缺乏Finder侧边栏的视觉外观和行为。

非常感谢您的帮助,以实现所需的行为。提前感谢您的协助。

英文:

When attempting to replicate the behaviour of Finder and SF Symbols in a macOS application using SwiftUI, I encountered difficulties with DisclosureGroup.

Here is my current code:

import SwiftUI

struct SidebarView: View {
    @State private var companiesExpanded = false
    
    var body: some View {
        VStack{
            DisclosureGroup(isExpanded: $companiesExpanded) {
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("Water", systemImage: "drop")
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("Sewage", systemImage: "toilet")
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("Electricity", systemImage: "bolt")
                }
            } label: {
                Text("Companies")
                    .font(.subheadline)
                    .fontWeight(.semibold)
            }
        }
    }
}

In this code, I attempted to use the DisclosureGroup to create collapsible sections in the sidebar, similar to what is seen in Finder and SF Symbols. However, the result is not the same. The DisclosureGroup does collapse the items, but it lacks the visual appearance and behaviour of Finder's sidebar.

I would greatly appreciate any help to achieve the desired behaviour. Thank you in advance for your assistance.

Finder collapse items (Goal):
折叠 macOS SwiftUI 侧边栏项目

SF Symbols (Goal):
折叠 macOS SwiftUI 侧边栏项目

My App (Actual):
折叠 macOS SwiftUI 侧边栏项目

答案1

得分: 1

这里提出了一些建议来解决一些问题。

  • 使用 .frame(..)Label 左对齐,.infinity 将使所有标签占据整个侧边栏的空间。
  • Label 颜色为 .primary
  • label 添加一些内边距
  • label 颜色为 .secondary
  • 使用底部的 Spacer 来稳定动画
import SwiftUI

struct SidebarView: View {
    @State private var companiesExpanded = true
    
    var body: some View {
        VStack {
            DisclosureGroup(isExpanded: $companiesExpanded) {
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("水", systemImage: "drop")
                        .foregroundColor(.primary)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("污水", systemImage: "star")
                        .foregroundColor(.primary)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("电力", systemImage: "bolt")
                        .foregroundColor(.primary)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
            } label: {
                Text("公司")
                    .font(.subheadline)
                    .fontWeight(.semibold)
                    .foregroundColor(.secondary)
                    .padding(5)
            }
        }
        Spacer()
    }
}

你可以通过自定义 DisclosureGroupStyle 来获得更多控制。

例如:
如何在SwiftUI中创建自定义的DisclosureGroup(下拉菜单)?

英文:

Here's a proposal to fix some of the issues.

  • align Label left with a .frame(..), .infinity will make all Labels take the space of the whole sidebar.

  • Label color .primary

  • give a little padding for the label

  • label color .secondary

  • stabilize the animation with a Spacer at the bottom

      import SwiftUI
    
      struct SidebarView: View {
      @State private var companiesExpanded = true
    
      var body: some View {
          VStack {
              DisclosureGroup(isExpanded: $companiesExpanded) {
                  NavigationLink(destination: CompaniesLibraryView()) {
                      Label("Water", systemImage: "drop")
                          .foregroundColor(.primary)
                          .frame(maxWidth: .infinity, alignment: .leading)
                  }
                  NavigationLink(destination: CompaniesLibraryView()) {
                      Label("Sewage", systemImage: "star")
                          .foregroundColor(.primary)
                          .frame(maxWidth: .infinity, alignment: .leading)
                  }
                  NavigationLink(destination: CompaniesLibraryView()) {
                      Label("Electricity", systemImage: "bolt")
                          .foregroundColor(.primary)
                          .frame(maxWidth: .infinity, alignment: .leading)
                  }
              } label: {
                  Text("Companies")
                      .font(.subheadline)
                      .fontWeight(.semibold)
                      .foregroundColor(.secondary)
                      .padding(5)
              }
          }
          Spacer()
      }
      }
    

You can have more control with a custom DisclosureGroupStyle.

For example:
How to make a custom DisclosureGroup (drop down) in SwiftUI?

答案2

得分: 0

通过在DisclosureGroup()中添加.framealignment: .topDisclosureGroup()将始终被推到顶部,并在关闭后不会再次居中。

struct SidebarView: View {
    @State private var companiesExpanded = false
    
    var body: some View {
        VStack{
            DisclosureGroup(isExpanded: $companiesExpanded) {
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("水", systemImage: "drop")
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("污水", systemImage: "toilet")
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("电力", systemImage: "bolt")
                }
            } label: {
                Text("公司")
                    .font(.subheadline)
                    .fontWeight(.semibold)
            }
            .frame(height: 100, alignment: .top) // 将 DisclosureGroup() 推到顶部
            .background(.gray) // 以查看框架
        }
    }
}
英文:

By adding .frame with alignment: .top to the DisclosureGroup(), the DisclosureGroup() will always be pushed to the top and won't be centred again after closing.

struct SidebarView: View {
    @State private var companiesExpanded = false
    
    var body: some View {
        VStack{
            DisclosureGroup(isExpanded: $companiesExpanded) {
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("Water", systemImage: "drop")
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("Sewage", systemImage: "toilet")
                }
                NavigationLink(destination: CompaniesLibraryView()) {
                    Label("Electricity", systemImage: "bolt")
                }
            } label: {
                Text("Companies")
                    .font(.subheadline)
                    .fontWeight(.semibold)
            }
            .frame(height: 100, alignment: .top) // Push DisclosureGroup() to the top
            .background(.gray) // To see frame
        }
    }
}

huangapple
  • 本文由 发表于 2023年7月3日 06:03:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76600964.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定