创建 SwiftUI 侧边栏

2023-12-31

我想使用 SwiftUI 构建一个非常简单的 iOS 14 侧边栏。 设置很简单,我有三个视图HomeView, LibraryView and SettingsView和代表每个屏幕的枚举。

enum Screen: Hashable {
   case home, library, settings
}

我的最终目标是根据尺寸类别在选项卡视图和侧边栏之间自动切换,但有些事情并不完全按预期工作。

全球国家由MainNavigationView,这也是我的根视图WindowGroup.

struct MainNavigationView: View {
    @State var screen: Screen? = .home
   
    var body: some View {
        NavigationView {
            SidebarView(state: $screen)
        }
        .navigationViewStyle(DoubleColumnNavigationViewStyle())
    }
}

The SidebarView是一个简单的List包含三个NavigationLink, 每人一个Screen.

struct SidebarView: View {
    @Binding var state: Screen?
    var body: some View {
        List {
            NavigationLink(
                destination: HomeView(),
                tag: Screen.home,
                selection: $state,
                label: {
                    Label("Home", systemImage: "house" )
                })
            NavigationLink(
                destination: LibraryView(),
                tag: Screen.library,
                selection: $state,
                label: {
                    Label("Library", systemImage: "book")
                })
            NavigationLink(
                destination: SettingsView(),
                tag: Screen.settings,
                selection: $state,
                label: {
                    Label("Settings", systemImage: "gearshape")
                })
        }
        .listStyle(SidebarListStyle())
        .navigationTitle("Sidebar")
    
    }
}

我用NavigationLink(destination:tag:selection:label)初始化程序,以便在我的中设置所选屏幕MainNavigationView这样我就可以将其重新用于我的TabView later.

然而,很多事情并不完全按照预期进行。

首先,在纵向模式iPad(我使用iPad Pro 11英寸模拟器)中启动应用程序时,启动应用程序时没有选择屏幕。只有在我点击之后Back在导航栏中,显示初始屏幕并显示我的主视图。

第二个奇怪的事情是绑定似乎设置为nil每当侧边栏被隐藏时。在横向模式下,视图按预期工作,但是当将侧边栏切换为隐藏然后再次显示时,选择会丢失。 内容视图保持正确,但侧边栏选择丢失。

这些只是SwiftUI错误或者是否有不同的方法来创建带有Binding?


您需要在NavigationView { },通常它是一个占位符,但你可以使用HomeScreen, e.g.

struct MainNavigationView: View {
    @State var screen: Screen? = .home
   
    var body: some View {
        NavigationView {
            SidebarView(state: $screen)
            HomeScreen()
        }
        .navigationViewStyle(DoubleColumnNavigationViewStyle())
    }
}

关于不重新选择的单元格 - 从 iOS 14.2 开始,没有列表选择绑定(当不处于编辑模式时),因此选择会丢失。虽然 List API 有一个$selectionparam,目前仅在 macOS 上支持。您可以在标题中看到该信息:

/// On iOS and tvOS, you must explicitly put the list into edit mode for
/// the selection to apply.

这有点复杂,但这意味着我们需要的侧边栏选择绑定仅适用于 macOS,在 iOS 上它仅适用于编辑模式下的多选(即复选标记)。原因可能是因为UITableView的选择是事件驱动的,也许无法转化为 SwiftUI 的状态驱动性质。如果您曾经尝试使用已推送到导航控制器上的视图进行状态恢复,并尝试在弹出时显示单元格取消突出显示动画,并且该表视图未加载并且单元格从未突出显示,那么您将明白我的意思了吗。同步加载表格、绘制所选单元格然后启动取消突出显示动画是一场噩梦。我预计 Apple 将在纯 SwiftUI 中重新实现 List、Sidebar 和 NavigationView 来克服这些问题,所以现在我们只能忍受它。

一旦解决了这个问题,事情就会变得简单List(selection:$screen) { }就像它在 macOS 上的工作方式一样。作为 iOS 上的解决方法,您可以按照自己的方式突出显示图标或文本,例如尝试使用粗体文本:

    NavigationLink(
        destination: HomeView(),
        tag: Screen.home,
        selection: $state,
        label: {
            Label("Home", systemImage: "house" )
        })
        .font(Font.headline.weight(state == Screen.home ? .bold : .regular))

紧凑时它看起来不太好,因为弹出主视图后,当行未突出显示时,粗体将被删除。在这种情况下,可能有一种方法可以禁用粗体。

您还应该注意另外 2 个错误:

  1. 在纵向中,侧边栏仅在第二次点击侧边栏导航按钮时显示。
  2. 在纵向模式下,如果您显示侧边栏并选择已显示的相同项目,则侧边栏不会消失。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建 SwiftUI 侧边栏 的相关文章

随机推荐

  • SELECT 类型查询是唯一可以嵌套的类型吗?

    是否可以将非选择查询 更新 插入 删除 嵌入到另一个查询中 类似于 选择内的插入 A single query select such and such from where insert into 基本答案 有CTEs 通用表表达式 ht
  • 如何从“workflow.Context”获取“context.Context”?

    我正在实现一个 Cadence 工作流程 需要使用以下命令调用函数context Context参数 我该如何获得context Context来自workflow Context 难道这只是一个问题ctx context Context
  • Unity HoloLens 应用程序作为 Windows 应用程序而不是 AR 执行

    我正在使用以下工具构建 HoloLens Unity 应用程序 统一 2018 3 14f1 视觉工作室 2017 Microsoft MixedReality Toolkit Unity Foundation v2 0 0 RC1 Ref
  • 动态表单上的 MVC 模型验证?

    我有以下模型 public class FileModel public int Id get set Required ErrorMessage Required StringLength 100 ErrorMessage Max is
  • 在 Android 中添加自定义字体到主题

    有没有办法在 Android 的主题中添加自定义字体 我读过了快速提示 自定义 Android 字体 http mobile tutsplus com tutorials android customize android fonts 但这
  • Uint8Array 到 ArrayBuffer

    所以我有一个 ArrayBuffer 它是我用新的 HTML5 文件阅读器作为 ArrayBuffer 读取的文件的文件内容 并且我可以通过执行以下操作将 ArrayBuffer 转换为 Uint8Array ab established
  • MVC Core2 中的 Ajax 调用错误请求

    我正在将一个网站折射到 MVC Core 2 对于我的大多数 Ajax 调用 我一直使用 Get 速记 没有任何问题 我有一个 AJAX 调用需要使用 ajax 并且由于某种原因我不断收到错误的请求错误 请记住 此代码当前正在 aspx 网
  • 如何更改列表视图文本颜色

    在我的应用程序中 我想更改列表视图文本颜色 在本例中 我使用 XML 文件进行列表视图 是否可以 如果是 请举例说明 性别 xml
  • C 中变量名后的冒号[重复]

    这个问题在这里已经有答案了 可能的重复 结构体声明中的冒号是什么意思 例如 1 7 16 或 32 https stackoverflow com questions 1604968 what does a colon in a struc
  • 如何在 Kotlin Flow 中过滤列表

    我正在使用替换当前的实现RxJava to Coroutines and Flow 我在使用一些时遇到一些问题Flow运营商 我正在尝试过滤 a 中的项目列表Flow在提供收集之前 Flow
  • Passport.authenticate() 使用 Promise 而不是自定义回调

    passport authenticate 我如何定义一个Promise而不是使用定制球背 如何使用passport authenticate 在这里引用 http www passportjs org docs authenticate
  • 如何使用变量名称将命名元素添加到 R 向量

    我想向向量 V 添加一个元素 例如 100 并使用变量 x 的值作为新元素的名称 我知道可以这样做 V c V 100 names V length V x 但我正在寻找一种简单的单行解决方案 如果有的话 我试过 V c V as name
  • 使用 C++ 中的 PCL 在同一窗口中查看多个点云

    我有两个点云 我想在同一个窗口中对其进行可视化 include
  • TFS 2010 通过文件系统构建发布

    我在 TFS 中有一个相当大的 MVC2 项目 它在签入时自动构建 持续集成 目前 完整构建的版本已转储到我们的开发 IIS 服务器上的网络共享上 Server wwwrootLatest TFS 当然会创建很多子文件夹 因为它只是进行构建
  • 类内递归

    我试图在类语句中放置一个递归公式 class SomeNode def init self a leng len a half leng 2 self firstnode a 0 0 self child1 SomeNode a i for
  • 从外部连接到在 docker 容器内运行的服务

    我有一个服务在 docker 容器 本地机器 中运行 我可以在 Ambari 服务配置中看到服务 URL 现在我想使用本地开发环境连接到该服务 我发现我可以连接到容器内的该 URL 但是当我在本地外部使用该 URL 时 连接被拒绝 Caus
  • 为什么 vector 不是 STL 容器?

    Scott Meyers 的书第 18 条有效的 STL 改进标准模板库使用的 50 种具体方法说要避免vector
  • 专门化主模板时,更专门化意味着什么?

    C 模板特化规则中提到的特化必须比主模板更加特化 下面的 1 代码片段会导致编译错误 这表明第二行并不更专业 但最后一个片段 2 的工作看起来非常接近 1 两个代码片段都是专门的int N as 0 那么为什么第一个片段被抱怨为 不更专业
  • spect.getmembers() 与 __dict__.items() 与 dir()

    谁能用足够的例子向我解释黑白有什么区别 gt gt gt import inspect gt gt gt inspect getmembers 1 and gt gt gt type 1 dict items and gt gt gt di
  • 创建 SwiftUI 侧边栏

    我想使用 SwiftUI 构建一个非常简单的 iOS 14 侧边栏 设置很简单 我有三个视图HomeView LibraryView and SettingsView和代表每个屏幕的枚举 enum Screen Hashable case