本例中节仿,1晤锥、我們展示的是為UIView擴展一個sd屬性。sd屬性是SDAutoLayout類型廊宪。2矾瘾、為UIView添加一個靜態(tài)sd屬性,可示自定義靜態(tài)方法或屬性
1箭启、聲明協(xié)議壕翩,并為協(xié)議提供默認實現(xiàn),添加sd屬性傅寡。
/** --------------------------------------------
* 為UIView擴展一個sd添加屬性放妈,然后再提供一個默認layout()函數(shù),返回的是SDAutoLayoutModel類
* 方便鏈式調(diào)用
* 防止UIView中有l(wèi)ayout方法赏僧,然后重名
* -----------------------------------------------
*/
public protocol SDAutoLayoutCompatible {
/// associatedtype關鍵字用來指定關聯(lián)類型
associatedtype T
/// 添加一個為只讀的關聯(lián)屬性:sd
var sd: T { get }
}
/// 協(xié)議擴展大猛,可提供默認實現(xiàn),返回一個SDAutoLayout類型對象。
extension SDAutoLayoutCompatible {
// sd:關聯(lián)SDAutoLayout類型的屬性 默認實現(xiàn)
public var sd: SDAutoLayout<Self> {
get {
return SDAutoLayout.init(self)
}
}
}
擴展屬性的類型淀零,一般為一個class類挽绩。
上面協(xié)議所擴展一個sd屬性,其類型為SDAutoLayout
/// 聲明一個類驾中,為此類擴展并指定類型
public final class SDAutoLayout<Base> {
public let base: Base
public init(_ base: Base) {
self.base = base
}
}
/// 擴展SDAutoLayout唉堪,并指定類型為UIView, 為其添加一個layout()方法
// 為UIView擴展的sd添加方法
extension SDAutoLayout where Base: UIView {
/// 可通過UIView().sd.layout().leftSpace來調(diào)用。防止layout方法重名
@discardableResult // 未使用的返回值警告消除
func layout() -> SDAutoLayoutModel {
return base.sd_layout()
}
}
UIView擴展實現(xiàn)SDAutoLayoutCompatible肩民,那么它就擁有了sd屬性
/// 為UIView添加一個擴展唠亚,并實現(xiàn)協(xié)議,讓它有sd關聯(lián)屬性持痰,默認為SDAutoLayout類型
extension UIView: SDAutoLayoutCompatible {}
2灶搜、為類或結構體添加靜態(tài)屬性、成員屬性
/** --------------------------------------------
* 為UIView擴展一個sd屬性,一個sd靜態(tài)屬性割卖,
* 方便鏈式調(diào)用
* 防止UIView中有l(wèi)ayout方法前酿,然后重名
* -----------------------------------------------
*/
public protocol SDAutoLayoutCompatible {}
/// 協(xié)議擴展,可提供默認實現(xiàn),返回一個SDAutoLayout類型對象鹏溯。
extension SDAutoLayoutCompatible {
// sd:關聯(lián)SDAutoLayout類型的屬性 默認實現(xiàn)
public var sd: SDAutoLayout<Self> {
get {
return SDAutoLayout.init(self)
}
}
// 靜態(tài)屬性
public static var sd: SDAutoLayout<Self>.Type {
get {
return SDAutoLayout<Self>.self
}
}
}
/// 聲明一個結構體罢维,為此類擴展并指定類型
public struct SDAutoLayout<Base> {
public let base: Base
public init(_ base: Base) {
self.base = base
}
}
/// 擴展SDAutoLayout,并指定類型為UIView, 為其添加一個layout屬性, 靜態(tài)方法或靜態(tài)屬性
// 要擴展sd屬性的方法或屬性都在這里實現(xiàn)即可
extension SDAutoLayout where Base: UIView {
/// 可通過UIView().sd.layout.leftSpace來調(diào)用丙挽。防止layout方法重名
var layout: SDAutoLayoutModel {
get {
return base.sd_layout()
}
}
/// 靜態(tài)方法
@discardableResult // 未使用的返回值警告消除
public static func getView() -> UIView {
DXLog(message: "通過sd靜態(tài)屬性調(diào)用方法UIView.init: \(Base.init())")
return Base.init()
}
/// 默認背景顏色
static var defaultBgColor: UIColor {
get {
return UIColor.green
}
}
}
/// 為UIView添加一個擴展肺孵,并實現(xiàn)協(xié)議,讓它有sd關聯(lián)屬性颜阐,默認為SDAutoLayout類型
extension UIView: SDAutoLayoutCompatible {}
3平窘、使用
靜態(tài)屬性的使用
let view = UIView.sd.getView()
self.view.backgroundColor = UIView.sd.defaultBgColor
實例屬性的使用
imageView!.sd.layout().leftTo(contentView, 10)
.topTo(contentView, 10)
.width(is: 70).height(is: 100)
textLabel!.sd.layout().centerYEqualTo(contentView)
.leftTo(imageView!, 10)
.rightTo(contentView, 10)
.autoHeight(0)// 高度自適配
4、 swift中Self 瞬浓、.self 初婆、.Type是什么
- Self關鍵字
- swfit5.1開始蓬坡, 可用
Self
替代類名來訪問靜態(tài)成員
class ListViewController: UITableViewController { static let cellReuseIdentifier = "list-cell-identifier" override func viewDidLoad() { super.viewDidLoad() tableView.register( ListTableViewCell.self, forCellReuseIdentifier: Self.cellReuseIdentifier ) } }
-
Self
在未知具體類型的上下文中動態(tài)引用實際上的類型猿棉,例如,通過在協(xié)議擴展中引用協(xié)議
的具體實現(xiàn)類型
extension Numeric { func incremented(by value: Self = 1) -> Self { return self + value } } 給Numeric協(xié)議擴展了一個自增的方法屑咳, 但是我們現(xiàn)在不知道具體自增的類型萨赁,使用Self作為返回類型,則可以動態(tài)獲取對應的類型: let num1 = 5.incremented() //num1: Int let num2 = 5.0.incremented() //num2: Double
- swfit5.1開始蓬坡, 可用
- .Type關鍵字
Swift 中的元類型用 .Type 表示兆龙。比如 Int.Type 就是 Int 的元類型杖爽。
類型與值有著不同的形式,就像 Int 與 5 的關系紫皇。元類型也是類似慰安,.Type 是類型,類型的 .self 是元類型的值聪铺。