此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结
说在前面 每种语言都有类似的属性,就是为了 一次定义,多处复用  的思想,减少代码的冗余。
自定义视图组件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import  SwiftUIstruct  YikunText : View {    var  text: String      var  body: some  View  {         Text (text)             .foregroundColor(.white)             .padding()             .background(.blue)     } } struct  ContentView : View  {    var  body: some  View  {         VStack {             YikunText (text: "易困Yikun" )             YikunText (text: "无限进步" )         }     } } 
这里我们封装了一个结构体 YikunText  ,然后就可以直接使用这个封装好的组件,与ContentView的区别不大,都遵循了 View  协议,目的是为了将视图的样式和布局代码进行封装,提高代码的复用性,在前端代码里很常见,比如三框架中就叫做组件 components  。
ViewModifier 视图修改器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import  SwiftUIstruct  YikunText : ViewModifier {    func  body (content : Content ) -> some  View  {         content             .foregroundColor(.white)             .padding()             .background(.blue)     } } struct  ContentView : View  {    var  body: some  View  {         VStack {             Text ("易困Yikun" )                 .modifier(YikunText ())             Text ("无限进步" )                 .modifier(YikunText ())         }     } } 
这次我们使用 ViewModifier  实现了相同的效果,它们的目的相同,都是为了方便地修改和定制视图。
定义方式不同:
自定义视图(如YikunText):通过定义一个遵循View协议的结构体来创建自定义视图。这个结构体有一个body计算属性,用于返回视图内容。在body中可以直接组合和定制多个视图,并设置它们的样式。 
ViewModifier:通过定义一个遵循ViewModifier协议的结构体来创建。这个结构体需要实现一个 body(content: Content) -> some View 方法,其中 content 是要被修改的视图,方法返回修改后的视图。 
 
应用方式不同:
自定义视图(如YikunText):通过创建自定义视图结构体的实例来使用。在其他视图中,可以像使用普通视图一样使用自定义视图,如在ContentView中使用 YikunText(text: “易困Yikun”)  。 
ViewModifier:通过视图的.modifier()方法来应用,如 Text(“易困Yikun”).modifier(YikunText())  。 
 
结合扩展extension来实现 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 import  SwiftUIstruct  YikunText : ViewModifier {    func  body (content : Content ) -> some  View  {         content             .foregroundColor(.white)             .padding()             .background(.blue)     } } extension  View {    func  titleStyle () -> some  View {         modifier(YikunText ())     } } struct  ContentView : View  {    var  body: some  View  {         VStack {             Text ("易困Yikun" )                 .titleStyle()             Text ("无限进步" )                 .titleStyle()         }     } } 
这种写法同样能实现上面的效果,它是利用 ViewModifier  来创建可复用的视图样式修改逻辑,并通过扩展(extension)为 View 类型添加了一个便捷的方法,使得多个视图能够方便地应用该样式。
结合上面实例实现水印效果 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 import  SwiftUIstruct  YikunText : ViewModifier {    func  body (content : Content ) -> some  View  {         content             .foregroundColor(.white)             .padding()             .background(.blue)     } } struct  Watermark : ViewModifier {    var  text: String      func  body (content : Content ) -> some  View  {         ZStack (alignment: Alignment .bottomTrailing){             content                          Text (text)                 .font(.caption)                 .foregroundColor(.white)                 .padding(5 )                 .background(.black)         }     } } extension  View {    func  titleStyle () -> some  View {         modifier(YikunText ())     }     func  watermarked (with  text : String ) -> some  View {         modifier(Watermark (text: text))     } } struct  ContentView : View  {    var  body: some  View  {         VStack {             Text ("无限进步" )                 .frame(width: 100 ,height: 100 )                 .titleStyle()                 .watermarked(with: "易困Yikun" )         }     } } 
Watermark 结构体部分:
同样遵循 ViewModifier  协议,并且额外接收一个 text  参数。
在 body 方法中,使用 ZStack 进行视图叠加布局,先放置传入的原始 content 视图,然后在右下角(通过 Alignment.bottomTrailing 对齐方式)添加一个文本水印。水印文本具有特定的样式,如设置为小字号(.caption 字体)、白色前景色、添加内边距以及黑色背景,实现了为视图添加自定义文本水印的功能。
高级进阶 网格布局 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 import  SwiftUIstruct  GridStack <Content : View >: View {    let  rows: Int      let  columns: Int      @ViewBuilder  let  content: (Int , Int ) -> Content           var  body: some  View {         VStack {             ForEach (0 ..< rows, id:\.self ){ row in                  HStack {                     ForEach (0 ..< columns,id:\.self ){ column in                          content(row, column)                     }                 }             }         }     } } struct  ContentView : View  {    var  body: some  View  {         GridStack (rows: 4 , columns: 4 ){ row, col in              Image (systemName: "\(row* 4  +  col) .circle" )             Text ("R\(row)  C\(col) " )         }     } } 
知识点 
泛型编程:GridStack  结构体,使得它可以处理不同类型的视图作为其内部单元格内容,提高了代码的复用性和通用性。这是一种很重要的编程思想,能够避免为不同的视图类型编写重复的相似代码,只要这些视图遵循 View  协议即可融入到 GridStack  的布局当中。 
视图构建与组合:
通过 VStack  和 HStack  以及 ForEach  循环的配合,展示了如何在 SwiftUI 中动态地构建复杂的视图布局结构。利用 ForEach 可以方便地根据数据(这里是行和列的索引)来重复生成视图元素,然后通过嵌套的布局容器将这些元素组合成想要的布局形式,比如这里构建出了网格布局。 
@ViewBuilder  属性包装器的运用,让闭包内构建视图变得更加简洁直观,它允许像在普通视图结构体的 body 里那样书写视图代码,使得代码的可读性更好,也符合 SwiftUI 中视图构建的语法习惯。 
 
尾随闭包语法:GridStack  实例时使用了尾随闭包语法,将原本应该写在括号内的闭包参数移到了括号外面,使代码更加简洁、易读,尤其是当闭包内容较多、逻辑较复杂时,这种语法能让代码结构更加清晰,是 Swift 语言中一种常用的提高代码可读性的语法特性。。