本機重點探討擴展的寫法
需求:給UIView 擴展一個獲取width 和height 的 屬性
extension UIView{
var width:CGFloat{
return self.frame.size.width
}
var height:CGFloat{
return self.frame.size.height
}
}
調(diào)用方式
self.view.width
self.view.height
分析:
調(diào)用方式非常簡單,但是但是,如果別人也寫了個一樣的擴展,或者系統(tǒng)框架以后也增加了一個這樣的屬性,你寫的這個就會報沖突的錯誤
有人說好辦,加個前綴,我們繼續(xù)改進一下
extension UIView{
var os_width:CGFloat{
return self.frame.size.width
}
var os_height:CGFloat{
return self.frame.size.height
}
}
調(diào)用:
self.view.os_width
self.view.os_height
這個是oc 延展過來的寫法,當然Swift 有自己更優(yōu)雅的寫法,過程有點復雜,我按照步驟寫
- 第一步 創(chuàng)建一個泛型結(jié)構(gòu)體,里面定義一個屬性,接受傳進來的值
struct Auto<Base>{
let base:Base
init(_ base:Base) {
self.base = base
}
}
- 第二步 定義一個協(xié)議
protocol Compatible{
associatedtype CompatableType
var os: CompatableType { get }
}
提示:
CompatableType 自定義變量 具體在實現(xiàn)時寫
os 這個一般寫自己的名字或者組織的名字
- 第三步 實現(xiàn)這個協(xié)議
extension Compatible{
var os:Auto<Self>{
return Auto(self)
}
}
提示:
Auto 是一個泛型的結(jié)構(gòu)體,Self 代表誰實現(xiàn)了協(xié)議Compatible 這個Self 就是誰
- 第四步 寫擴展協(xié)議
extension Auto where Base: UIView{
/// 擴展方法寫到這個
var width:CGFloat{
return self.base.frame.size.width
}
var height:CGFloat{
return self.base.frame.size.height
}
}
注意:
這個時候,你如果調(diào)用擴展的方法是掉不出來的,因為UIView 下載是沒有實現(xiàn)協(xié)議Compatible 所以不能調(diào)用os這個屬性, 剛才說Auto 是泛型,where 后面的意思就是Base 如果是UIView的類型己儒,這個擴展才有效,即給base 為UIView 類型的對象擴展屬性,這個時候系統(tǒng)會自動推斷Base 為UIView 類型,所以能調(diào)出frame的屬性
- 第五步 讓UIView 實現(xiàn)協(xié)議
extension UIView:Compatible{
}
完成上面的五步,就完成了我們的擴展,看一下如何調(diào)用
print(self.view.os.width)
print(self.view.os.height)
運行結(jié)果:
375.0
667.0