CSS 相信很多前端開發(fā)者都很熟悉,全稱為Cascading Style Sheets
, 層疊樣式表匆笤。
在2019年研侣,Apple 推出SwiftUI后,iOS開發(fā)者炮捧,也可以在Swift中使用“CSS”了庶诡。 這就是SwiftUI中的ViewModifier。
通過ViewModifier咆课, 開發(fā)者可以向View添加accessibility的功能末誓,可以調整View和內部元素的樣式,布局书蚪,可以響應事件基显,還可以有條件的顯示模態(tài)視圖等。
任何符合View協(xié)議的視圖善炫,都可以通過ViewModifier來操作撩幽。
Text("Hello, World!")
.foregroundColor(.red)
上述代碼中.foregroundColor(.red)
就是一個標準的對ViewModifier的調用,也是對樣式的基本操作箩艺,具體有哪些操作窜醉,可以查看SwiftUI-Cheat-Sheet。
同時呢艺谆,ViewModifier也支持鏈式操作榨惰。
Text("Title")
.frame(width: 100)
.border(Color.gray)
Text("Title")
.border(Color.gray)
.frame(width: 100)
這里要注意,和CSS不同的是静汤,ViewModifier的調用順序琅催,會影響到最終樣式的呈現。
為什么會有這樣的現象呢虫给?
要回答這個問題藤抡,首先就要來看看,怎么自定義實現一個ViewModifier抹估。
struct BlueTitle : ViewModifier {
func body(content: Content) -> some View {
content
.font(.title)
.foregroundColor(.blue)
}
}
extension View {
func blueTitle() -> some View {
self.modifier(BlueTitle())
}
}
struct ContentView: View {
var body: some View {
Text("Hello World")
.blueTitle()
}
}
上述代碼缠黍,描述了如何自定義一個名為BlueTitle的struct, 作用是改變content中所有的元素樣式药蜻,改為title的大小瓷式,并且將顏色改為藍色替饿。這里我們注意到,BlueTitle 遵循了ViewModifier的協(xié)議贸典。并返回了some View
视卢。 所以ViewModifier實際返回的是一個已經應用了具體配置的View,而不是一個可以在某一范圍內全局應用的配置表廊驼。理解了這一點腾夯,也就能理解,為什么改變了順序蔬充,就改變了視圖呈現的結果。
和CSS一樣班利,父元素ViewModifier的作用饥漫,是可以被子元素覆蓋的。
VStack {
Text("Title")
.font(.title) // Override the font of this view.
Text("First body line.")
Text("Second body line.")
}
.font(.body)
在上面的例子里罗标,Title
的樣式是.title
庸队,而不是.body
。
當然闯割,ViewModifier也不是都能覆蓋的彻消。
在這里要注意的是,如果某個View被通用修飾符(ViewModifier)修飾后宙拉,就不能再使用特定的修飾符了宾尚。
Text("Hello, world!")
.padding()
.bold()
上面就是一個反例,bold()是Text的特定修飾符谢澈,僅能作用于Text煌贴;當Text被padding()
修飾后,類型就變成了View锥忿,便不能在使用.bold()
進行修飾了牛郑。 如果一定要用,那就需要將兩個調用順序做個調整敬鬓。
當然淹朋,ViewModifier也可以傳參數使用。如下所示:
struct Watermark: ViewModifier {
var text: String
func body(content: Content) -> some View {
ZStack(alignment: .bottomTrailing) {
content
Text(text)
.font(.caption)
.foregroundColor(.white)
.padding(5)
.background(Color.black)
}
}
}
struct ContentView: View {
var body: some View {
Color.blue
.frame(width: 300, height: 200)
.watermarked(with: "Hacking with Swift")
}
}
參考: