iOS SwiftUI基础学习(二)

第四节 创建列表
接上一篇,我们已经完成了单个Cell的实现,接下来我们直接使用List View(类似UITableView)来完成列表。
参考我们之前使用Stack,我们在单个Cell的外面添加一个List View试试

struct ContentView: View {
    var body: some View {
        List {
            HStack {
                Image("埃及-金字塔-预览")
                VStack(alignment: .leading) {
                    Text("金字塔")
                    Text("埃及")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                }
            }
        }
    }
}

可以看到效果已经出来了,已经看到列表的雏形了。
由于我们目前只有1个数据,所以只展示了一行,我们可以在列表中添加多个重复的数据



除了手动写代码添加List View之外,我们还可以这样操作:按住command选中HStack,点击鼠标左键,然后选择“Embed in List”,Xcode就可以自动为我们添加List的代码,并且可以看到设置数据的代码


struct ContentView: View {
    var body: some View {
        List(0 ..< 5) { item in
            Image("埃及-金字塔-预览")
            VStack(alignment: .leading) {
                Text("金字塔")
                Text("埃及")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
        }
    }
}

第五节 设置List数据
在这之前我们一直是使用固定的单个数据,如果要使用列表,就必须有数据源(DataSource)
这里我们创建一个新的文件 Scenery.swift,用来设置数据,快捷键 command+N 选择 Swift File



我们首先创建一个结构体,并预设好我们需要的属性的名称

struct Scenery : Identifiable {
    var id: Int
    var name: String
    var thumbnailName: String
    var imageName: String
    var location: String
}

这里的 Identifiable 需要注意一下,它是为类或值类型提供稳定的身份的协议。可以理解为这个类对象的唯一标识符,我们在使用数据的时候,需要找到对应的数据,那么实现了这个Identifiable协议后,系统就会通过它的唯一id找到它。
除了id之外,其他几个数据都非常好理解,它们分别是:名称、缩略图名称、图片名称、地址。
在定义完属性后,我们就开始输入数据了
定义一个 sceneries 数组,输入“Scenery(” 这个时候你会发现Xcode会自动生成一个初始化方法,我们以此填入数据


let sceneries = [
    Scenery(id: 1001, name: "金字塔", thumbnailName: "埃及-金字塔-预览", imageName: "埃及-金字塔-黄昏", location: "埃及")
]

知识补充:在Xcode中添加图片素材非常简单,只需要将图片全选后,拖拽到Assets.xcassets这个文件目录下就可以了,如下图所示


OK,到这里我们就完成了数据的创建,接下来我们将刚才的数据放到List View里面试试
在List View中替换原来写死的数据

struct ContentView: View {
    var body: some View {
        List(sceneries) { item in
            Image(item.thumbnailName)
            VStack(alignment: .leading) {
                Text(item.name)
                Text(item.location)
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
        }
    }
}

添加完代码后,在右边画布区域重新resume一下就可以看到画面了



接下来我们接续添加剩余的数据

let sceneries = [
    Scenery(id: 1001, name: "金字塔", thumbnailName: "埃及-金字塔-预览", imageName: "埃及-金字塔-黄昏", location: "埃及"),
    Scenery(id: 1002, name: "马丘比丘", thumbnailName: "秘鲁-马丘比丘-预览", imageName: "秘鲁-马丘比丘-白天", location: "秘鲁"),
    Scenery(id: 1003, name: "乌尤尼盐湖", thumbnailName: "玻利维亚-乌尤尼盐湖-预览", imageName: "玻利维亚-乌尤尼盐湖-近景", location: "玻利维亚"),
    Scenery(id: 1004, name: "南极洲", thumbnailName: "南极洲-预览", imageName: "南极洲-陆地", location: "南极洲"),
    Scenery(id: 1005, name: "复活岛", thumbnailName: "太平洋-复活岛-预览", imageName: "太平洋-复活岛-白天", location: "太平洋"),
    Scenery(id: 1006, name: "加拉帕格斯群岛", thumbnailName: "太平洋-加拉帕格斯群岛-预览", imageName: "太平洋-加拉帕格斯群岛-海上", location: "太平洋"),
    Scenery(id: 1007, name: "塞伦盖蒂", thumbnailName: "坦桑尼亚-塞伦盖蒂-预览", imageName: "坦桑尼亚-塞伦盖蒂-草原", location: "坦桑尼亚"),
    Scenery(id: 1008, name: "威尼斯", thumbnailName: "意大利-威尼斯-预览", imageName: "意大利-威尼斯-白天", location: "意大利"),
    Scenery(id: 1009, name: "泰姬陵", thumbnailName: "印度-泰姬陵-预览", imageName: "印度-泰姬陵-白天", location: "印度"),
    Scenery(id: 1010, name: "巨石阵", thumbnailName: "英国-巨石阵-预览", imageName: "英国-巨石阵-白天", location: "英国")
]

第六节 添加导航栏和跳转链接
SwiftUI的导航栏和UIKit中的导航栏有点不一样,SwiftUI的NavigationView是针对某一个视图控件来说的,而在UIKit中我们通常是对控制器进行添加导航栏。
有了之前List View的经验,我们尝试添加导航栏,在List View外面添加一个层NavigationView
然后我们发现,在右边画布的顶部就出现了一篇空白区域



接下来为导航栏添加标题,我们先找到文档看下官方是如何写的

    /// Sets the title in the navigation bar for this view.
    ///
    /// Use `navigationBarTitle(_:)` to set the title of the navigation bar.
    /// This modifier only takes effect when this view is inside of and visible
    /// within a ``NavigationView``.
    ///
    /// The example below shows setting the title of the navigation bar using a
    /// ``Text`` view:

     struct FlavorView: View {
         let items = ["Chocolate", "Vanilla", "Strawberry", "Mint Chip",
                      "Pistachio"]
         var body: some View {
             NavigationView {
                 List(items, id: \.self) {
                     Text($0)
                 }
                 .navigationBarTitle(Text("Today's Flavors"))
             }
         }
}

有了官方的教学,我们直接照葫芦画瓢

struct ContentView: View {
    var body: some View {
        NavigationView {
            List(sceneries) { item in
                Image(item.thumbnailName)
                VStack(alignment: .leading) {
                    Text(item.name)
                    Text(item.location)
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                }
            }
            .navigationBarTitle(Text("风景名胜"))
        }
    }
}

完成导航栏后,接下来需要让List View的每一行都可以点击跳转到下一个页面
在SwiftUI中使用NavigationLink来触发跳转事件,与OC相比,更简洁了。不需要做事件绑定,只需要在对应的区域写下NavigationLink就可以。
我们使用简单的 “NavigationLink.destination: label:” 这个方法,destination就是跳转的View,label是链接的描述,可以根据需要显示不同描述。

struct ContentView: View {
    var body: some View {
        NavigationView {
            List(sceneries) { item in
                Image(item.thumbnailName)
                VStack(alignment: .leading) {
                    Text(item.name)
                    Text(item.location)
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                }
                NavigationLink(
                    destination: Text("Destination"),
                    label: {
                        Text("Navigate")
                    })
            }
            .navigationBarTitle(Text("风景名胜"))
        }
    }
}

我们把destination中的Text替换为item.name,然后把label中的Text的内容去掉,点击右边画布顶部第一个的“播放”按钮,就可以实现运行的效果了。
在页面刷新之后,点击List View的每一行,都可以看到跳转。


到这里我们就已经完成了第一个页面的全部内容了,是不是非常简单!
我们可以看到代码区域只用了不到30行,就实现了一个List View和跳转功能。
如果换到OC中的话,光是繁杂的delegate就不止这点代码了,更不用说要创建和布局UI控件。

你可能感兴趣的:(iOS SwiftUI基础学习(二))