1. Generics 泛型的定义及使用
1.1 创建使用泛型的实例 GenericsBootcamp.swift
import SwiftUI
struct StringModel {
let info: String?
func removeInfo() -> StringModel{
StringModel(info: nil)
}
}
struct BoolModel {
let info: Bool?
func removeInfo() -> BoolModel{
BoolModel(info: nil)
}
}
// CustomType = T
struct GenericModel<T>{
let info: T?
func removeInfo() -> GenericModel{
GenericModel(info: nil)
}
}
class GenericsViewModel: ObservableObject{
/// 定义具体类型
@Published var stringModel = StringModel(info: "hello, word!")
@Published var boolModel = BoolModel(info: true)
/// 定义泛型
@Published var genericStringModel = GenericModel(info: "Hello, world!")
@Published var genericBoolModel = GenericModel(info: true)
func removeData(){
stringModel = stringModel.removeInfo()
boolModel = boolModel.removeInfo()
genericStringModel = genericStringModel.removeInfo()
genericBoolModel = genericBoolModel.removeInfo()
}
}
/// 泛型 View
struct GenericView<T: View>: View{
let content: T
let title: String
var body: some View{
VStack {
Text(title)
content
}
}
}
/// 泛型
struct GenericsBootcamp: View {
@StateObject private var viewModel: GenericsViewModel
init() {
_viewModel = StateObject(wrappedValue: GenericsViewModel())
}
var body: some View {
VStack {
GenericView(content: Text("custom content"), title: "new View")
Text(viewModel.stringModel.info ?? "No data")
Text(viewModel.boolModel.info?.description ?? "No data")
Text(viewModel.genericStringModel.info ?? "No data")
Text(viewModel.genericBoolModel.info?.description ?? "No data")
}.onTapGesture {
viewModel.removeData()
}
}
}
struct GenericsBootcamp_Previews: PreviewProvider {
static var previews: some View {
GenericsBootcamp()
}
}
1.2 效果图:
2. ViewBuilder 视图构造器的定义及使用
2.1 创建视图构造器的实例 ViewBuilderBootcamp.swift
import SwiftUI
/// 常规标题视图
struct HeaderViewRegular: View{
let title: String
let description: String?
let iconName: String?
var body: some View{
VStack(alignment: .leading) {
Text(title)
.font(.largeTitle)
.fontWeight(.semibold)
if let description = description{
Text(description)
.font(.callout)
}
if let iconName = iconName{
Image(systemName: iconName)
}
RoundedRectangle(cornerRadius: 5)
.frame(height: 2)
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
}
}
/// 通用的标题视图
struct HeaderViewGeneric<Content: View>: View {
let title: String
// 泛型,可以为任何类型
let content: Content
init(title: String, @ViewBuilder content: () -> Content) {
self.title = title
self.content = content()
}
var body: some View{
VStack(alignment: .leading) {
Text(title)
.font(.largeTitle)
.fontWeight(.semibold)
content
RoundedRectangle(cornerRadius: 5)
.frame(height: 2)
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
}
}
/// 自定义水平堆栈视图
struct CustomHStack<Content: View>:View{
let content: Content
init(@ViewBuilder content: () -> Content){
self.content = content()
}
var body: some View{
HStack {
content
}
}
}
/// 视图构造器
struct ViewBuilderBootcamp: View {
var body: some View {
VStack {
HeaderViewRegular(title: "New Title", description: "Hello", iconName: "heart.fill")
HeaderViewRegular(title: "Another title", description: nil, iconName: nil)
HeaderViewGeneric(title: "Generic 3") {
VStack {
Text("Hello, world!")
Image(systemName: "bolt.fill")
}
}
CustomHStack {
Text("Hi")
Text("Wo")
}
HStack {
Text("Hi")
Text("Wo")
}
Spacer()
}
}
}
/// 本地视图构造器
struct LocalViewBuilder: View{
enum ViewType {
case one, two, three
}
let type: ViewType
/// 视图构造器
var body: some View {
VStack {
headerSection
}
}
/// 标题部分 头部分
@ViewBuilder private var headerSection: some View{
switch type {
case .one:
oneView
case .two:
twoView
case .three:
threeView
}
}
/// 视图一
@ViewBuilder private var oneView: some View{
Text("One!")
}
/// 视图二
private var twoView: some View{
VStack {
Text("Two 2")
Image(systemName: "heart.fill")
}
}
/// 视图三
private var threeView: some View{
Image(systemName: "heart.fill")
}
}
struct ViewBuilderBootcamp_Previews: PreviewProvider {
static var previews: some View {
//ViewBuilderBootcamp()
LocalViewBuilder(type: .one)
}
}
2.2 效果图: