本文转载自微信公众号《Swift社区》,作者魏贤智。转载本文请联系Swift社区公众号。每当我们将修改器应用于SwiftUI视图时,我们实际上是在创建一个应用了更改的新视图——我们不仅仅是在修改现有视图。如果你仔细想想,这种行为是有道理的——我们的视图只保留我们给它们的确切属性,所以如果我们设置背景颜色或字体大小,就没有地方可以存储这些数据。我们将在下一章中了解为什么会发生这种情况,但首先,我想了解这种行为的实际含义。看看这段代码:Button("HelloWorld"){//donothing}.background(Color.red).frame(width:200,height:200)你认为它运行时会是什么样子?您可能错了消失了:您不会看到中间带有“HelloWorld”的200x200红色按钮。相反,您会看到一个200x200的空方块,中间有“HelloWorld”,“HelloWorld”周围有一个红色矩形。如果您考虑修饰符的工作原理,您就会明白为什么会这样:每个修饰符都会创建一个应用该修饰符的新结构,而不是在视图上设置属性。您可以通过查询视图主体的类型来深入了解SwiftUI。修改按钮如下:Button("HelloWorld"){print(type(of:self.body))}.background(Color.red).frame(width:200,height:200)Swift的type(of:)方法打印特定值的确切类型,在本例中它打印以下内容:ModifiedContent你可以在这里看到两件事:每次我们修改视图时,SwiftUI使用以下泛型来应用修饰符:ModifiedContent当我们应用多个修饰符时,它们堆叠在一起:ModifiedContent要了解类型是什么,请从最内层的类型开始,然后向上:给它一个框架。如您所见,我们正在堆叠ModifiedContent类型——每个视图都需要一个要转换的视图和要进行的实际更改,而不是直接修改视图。这意味着修饰符的顺序很重要。如果我们在设置框架后重写代码以使用背景颜色,那么您将得到预期的结果:Button("HelloWorld"){print(type(of:self.body))}.frame(width:200,height:200).background(Color.red)现在最好的思考方式是想象SwiftUI在每个修改器之后渲染你的视图。因此,每当您说.background(Color.red)时,无论您给它什么框架,它都会将背景颜色更改为红色。如果稍后展开框架,它不会重新加载,因为背景已被使用。当然,这并不是SwiftUI的实际工作方式,因为如果这样做,那将是一场性能噩梦,但它是学习时使用的一种巧妙的思维捷径。使用修饰符的一个重要副作用是我们可以多次应用相同的效果:每个修饰符只是简单地添加到前一个。例如,SwiftUI为我们提供了padding()修饰符,它在视图周围添加了一些空间,这样它就不会将它推到其他视图或屏幕边缘。如果我们应用填充,然后是背景颜色,然后是更多的填充和不同的背景颜色,我们可以为视图提供多个边框,如下所示:Text("HelloWorld").padding().background(Color.red).padding().background(Color.blue).padding().background(Color.green).padding().background(Color.yellow)翻译自Whymodifierordermatters[1]References[1]Whymodifierordermatters:https://www.hackingwithswift.com/books/ios-swiftui/why-modifier-order-matters
