Sidebar navigation in SwiftUI

栏目: IT技术 · 发布时间: 5年前

内容简介:We already covered master-detail navigation in SwiftUI on my blog. But today, I want to talk about new sidebar navigation that landed this year into iOS and macOS worlds. We will learn how to build a three-column navigation flow by usingA sidebar provides

We already covered master-detail navigation in SwiftUI on my blog. But today, I want to talk about new sidebar navigation that landed this year into iOS and macOS worlds. We will learn how to build a three-column navigation flow by using NavigationView in SwiftUI.

Sidebar navigation in SwiftUI

A sidebar provides app-level navigation and quick access to top-level collections of content in your app. Selecting an item in the sidebar allows people to navigate to a specific piece of content. For example, the sidebar in Mail shows a list of all mailboxes. People can select a mailbox to access its list of messages, and select a specific message to display in the content pane.

To learn about building navigation using NavigationView and NavigationLink , take a look at my “Navigation in SwiftUI” post.

Let’s build a prototype of a mail app that uses three-column navigation. SwiftUI provides NavigationView that allows us to create a master-detail flow. You can put up to three children inside a NavigationView . In this case, SwiftUI will place views side-by-side. But let’s start with declaring our data model.

import SwiftUI

struct Mail: Identifiable, Hashable {
    let id = UUID()
    let date: Date
    let subject: String
    let body: String
    var isFavorited = false
}

final class MailStore: ObservableObject {
    @Published var allMails: [String: [Mail]] = [
        "Inbox": [ .init(date: Date(), subject: "Subject1", body: "Very long body...") ],
        "Sent": [ .init(date: Date(), subject: "Subject2", body: "Very long body...") ],
    ]
}

In the listing above, we create a simple mail store that we will use as a datastore for our prototype. Now let’s move forward by implementing the first column of our navigation flow.

struct Sidebar: View {
    @ObservedObject var store: MailStore
    @Binding var selectedFolder: String?
    @Binding var selectedMail: Mail?

    var body: some View {
        List(selection: $selectedFolder) {
            ForEach(Array(store.allMails.keys), id: \.self) { folder in
                NavigationLink(
                    destination: FolderView(
                        title: folder,
                        mails: store.allMails[folder, default: []],
                        selectedMail: $selectedMail)
                ) {
                    Text(folder).font(.headline)
                }
            }
        }.listStyle(SidebarListStyle())
    }
}

As you can see, we create a view called sidebar. It needs an instance of store object to access our emails and two bindings that we will use to bind the current folder and selected email. We also use the new SidebarListStyle to apply a brand new styling to our list that available on iOS 14 and macOS Big Sur.

struct FolderView: View {
    let title: String
    let mails: [Mail]
    @Binding var selectedMail: Mail?

    var body: some View {
        List(selection: $selectedMail) {
            ForEach(mails) { mail in
                NavigationLink(
                    destination: MailView(mail: mail),
                    tag: mail,
                    selection: $selectedMail
                ) {
                    VStack(alignment: .leading) {
                        Text(mail.subject)
                        Text(mail.date, style: .date)
                    }
                }
            }
        }.navigationTitle(title)
    }
}

Here we have the FolderView struct that we use to display a list of emails in the folder. FolderView also needs the binding for a selected email. Whenever the user selects an email in the list, SwiftUI sets the value of the binding and updates the view hierarchy. Now let’s take a look at MailView .

struct MailView: View {
    let mail: Mail

    var body: some View {
        VStack(alignment: .leading) {
            Text(mail.subject)
                .font(.headline)
            Text(mail.date, style: .date)
            Text(mail.body)
        }
    }
}

OK, now we have all the needed pieces to build our three-column navigation flow. As I mentioned earlier, we will put our column views inside a NavigationView .

@main
struct TestProjectApp: App {
    @StateObject var store = MailStore()
    @State private var selectedLabel: String? = "Inbox"
    @State private var selectedMail: Mail?

    var body: some Scene {
        WindowGroup {
            NavigationView {
                Sidebar(
                    store: store,
                    selectedFolder: $selectedLabel,
                    selectedMail: $selectedMail
                )

                if let label = selectedLabel {
                    FolderView(
                        title: label,
                        mails: store.allMails[label, default: []],
                        selectedMail: $selectedMail
                    )
                } else {
                    Text("Select label...")
                }

                if let mail = selectedMail {
                    MailView(mail: mail)
                } else {
                    Text("Select mail...")
                }
            }
        }
    }
}

As you can see, we have NavigationView , which is the root of our app scene. We also define two state properties which describe selected label and email. We pass bindings to these state properties down into the view hierarchy, and whenever the user selects the folder or email, SwiftUI updates bindings and route our navigation. Thanks to SwiftUI’s declarative nature, the code above works great both on iPhone, where it uses the single column navigation and iPad where is uses sidebar navigation.

Sidebar navigation plays a huge role in new Human Interface Guidelines . It is effortless to implement in SwiftUI using NavigationView . I hope you enjoy the post. Feel free to follow me on Twitter and ask your questions related to this article. Thanks for reading, and see you next week!


很遗憾的说,推酷将在这个月底关闭。人生海海,几度秋凉,感谢那些有你的时光。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

谷歌和亚马逊如何做产品

谷歌和亚马逊如何做产品

梅 (Chris Vander Mey) / 刘亦舟 / 人民邮电出版社 / 2014-6-1 / CNY 49.00

软件在交付之前,面临产品、方案、项目和工程管理等诸多挑战,如何做到游刃有余并打造出极致产品?本书作者曾任谷歌和亚马逊高级产品经理、现任Facebook产品经理,他将自己在达特茅斯学院钻研的理论知识和在领先的互联网公司十年的工作经验尽数总结在此,从定义产品开始,一步步指导你完成管理项目、迭代、发布、市场推广等交付流程,让你身临其境地体验到极致产品如何取得成功。 本书主要内容: 如何清晰定......一起来看看 《谷歌和亚马逊如何做产品》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

html转js在线工具
html转js在线工具

html转js在线工具