主页 SwiftUI 点击List的Row时Push到一个新的View
Post
Cancel

SwiftUI 点击List的Row时Push到一个新的View

通常我们在列表 UITableView 或者 UICollectionView 中点击 Cell 来 Push 到一个新的页面会使用对应的代理方法 didSelectRowAt,然而在 SwiftUI 中没有对应的代理属性,也没有类似的可以 push 的API,那么如何在 SwiftUI 中 push 一个 View 呢?那就是使用 NavigationLink

在 SwiftUI 中 NavigationLink 首先是一个 View,而且他可以控制导航 presentation,因此我们可以利用这个特性来实现当列表的某个Cell 被点击的时候可以 push 到一个新的页面。通常我们实现信息列表如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
struct Message: Identifiable {
    var id = UUID()
    var content: String
    var number: String
}

struct MessageRow: View {
    var message: Message
    var body: some View {
        VStack(alignment: .leading) {
            Text(message.content)
                .font(.body)
            Text(message.number)
                .font(.callout)
        }
    }
}

struct MessageListView: View {
    private var messages = [
        Message(content: "您尾号8888卡,余额1000,000,000。【工商银行】", number: "95588"),
        Message(content: "感谢您申请招行信用卡,下载掌上生活,自助开卡。【招商银行】", number: "95555"),
        Message(content: "当前话费余额:1000.2元。", number: "10086"),
        Message(content: "Apple Store:订单*****中的商品已配送成功。希望您喜欢。", number: "10069030049001"),
    ]
    
    var body: some View {
        NavigationView {
            List(messages) { message in
                MessageRow(message: message)
            }
                .navigationTitle("信息")
        }
    }
}

下面的 MessageDetail 是 Cell 点击后展示详细的信息视图,

1
2
3
4
5
6
7
8
9
struct MessageDetail: View {
    var message: Message
    var body: some View {
        VStack {
            Text(message.content)
        }
            .navigationTitle("来自\(message.number)的消息")
    }
}

现在一切准备就绪,只需要实现点击跳转的功能了。那么我们需要做的就是把列表的 Cell 用 NavigationLink 包起来就能实现push的功能了。封装后 Cell 的代码如下

1
2
3
4
5
NavigationLink(
    destination: MessageDetail(message: message),
    label: {
        MessageRow(message: message)
    })

其实就是用 NavigationLinkMessageDetail(message:)MessageRow(message:) 链接了起来,NavigationLink 收到点击的事件后执行了 push 操作。下面是完整的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
struct Message: Identifiable {
    var id = UUID()
    var content: String
    var number: String
}

struct MessageRow: View {
    var message: Message
    var body: some View {
        VStack(alignment: .leading) {
            Text(message.content)
                .font(.body)
            Text(message.number)
                .font(.callout)
        }
    }
}

struct MessageListView: View {
    private var messages = [
        Message(content: "您尾号8888卡,余额1000,000,000。【工商银行】", number: "95588"),
        Message(content: "感谢您申请招行信用卡,下载掌上生活,自助开卡。【招商银行】", number: "95555"),
        Message(content: "当前话费余额:1000.2元。", number: "10086"),
        Message(content: "Apple Store:订单*****中的商品已配送成功。希望您喜欢。", number: "10069030049001"),
    ]
    
    var body: some View {
        NavigationView {
            List(messages) { message in
                NavigationLink(
                    destination: MessageDetail(message: message),
                    label: {
                        MessageRow(message: message)
                    })
            }
            .navigationTitle("信息")
        }
    }
}


struct MessageDetail: View {
    var message: Message
    var body: some View {
        VStack {
            Text(message.content)
                .font(.headline)
                .padding(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 20))
                .lineLimit(2)
                //设置多行文本的对齐方式
                .multilineTextAlignment(.leading)
        }
        .navigationTitle("来自\(message.number)的消息")
    }
}

效果

该博客文章由作者通过 CC BY 4.0 进行授权。

文章目录

iOS 中赏心悦目的动画

SwiftUI 利用Paths创建折线图