1.声明一个类RoundCorner
public final class RoundCorner<Base> {
public let base: Base
public init(_ base: Base){
self.base = base
}
}
2.声明一个空协议,协议名RoundCornerCompatible
public protocol RoundCornerCompatible {
}
3.在协议扩展中,添加一个只读属性dx
,返回一个RoundCorner
对象
public extension RoundCornerCompatible {
public var dx: RoundCorner<Self> {
get { return RoundCorner(self) }
}
}
4.将所需要实现.dx
语法的Base
类遵守RoundCornerCompatible
协议,按照以往经验,遵守协议,实现协议的方法,但是Swift可以给协议添加可选属性(类似可选方法),凡是遵守这个协议RoundCornerCompatible
的类,便拥有了.dx这个属性.
这个.dx这个属性实际上是我们之前自定义的RoundCorner
的一个泛型实例.
extension UIView : RoundCornerCompatible {}
到现在为止,凡是UIView的子类,便可以使用.dx
,而这个.dx
实际上就是RoundCorner
这个实例对象,下面给这个对象添加自定义的方法
5.在RoundCorner
的扩展中,添加定义的方法
extension RoundCorner where Base: UIView{
/// 设置一个四角圆角
///
/// - Parameters:
/// - radius: 圆角半径
/// - cornerColor: 圆角背景色
public func roundCorner(radius: CGFloat,cornerColor: UIColor) {
base.layer.dx_roundCorner(radius: radius, cornerColor: cornerColor)
}
/// 设置一个普通圆角
///
/// - Parameters:
/// - radius: 圆角半径
/// - cornerColor: 圆角背景色
/// - corners: 圆角位置
public func roundCorner(radius: CGFloat,cornerColor: UIColor,corners: UIRectCorner) {
base.layer.dx_roundCorner(radius: radius, cornerColor: cornerColor, corners: corners)
}
/// 设置一个带边框的圆角
///
/// - Parameters:
/// - radius: 圆角半径
/// - cornerColor: 圆角背景色
/// - corners: 圆角位置
/// - borderColor: 边框颜色
/// - borderWidth: 边框线宽
func roundCorner(radii: CGSize,cornerColor: UIColor, corners: UIRectCorner, borderColor: UIColor, borderWidth: CGFloat) {
base.layer.dx_roundCorner(cornerRadii: radii, cornerColor: cornerColor, corners: corners, borderColor: borderColor, borderWidth: borderWidth)
}
}
使用示例
let circle = UIView()
circle.dx.roundCorner(radius: 15/2, cornerColor: color)
label.dx.roundCorner(radius: 20/2, cornerColor: UIColor.white,corners: [.topLeft,.topRight, .bottomRight, .bottomLeft])
简单解析一下
此处.dx
语法拿到是RoundCorner
这个泛型实例对象,而之后链式调用的roundCorner(radius: CGFloat,cornerColor: UIColor)
方法,实际上是RoundCorner
这个泛型实例对象进行的调用,这个泛型实例对象RoundCorner
内部拥有这一个base
就是遵守了RoundCornerCompatible
这个协议的UIView
重新组织一下语言
绕了半天,RoundCorner
这个就相当于一个代理,它内部拥有一个base
就是方法调用者,例如label
,而这个代理拥有某个功能,比如切圆角的功能,调用者需要遵守协议,那么你就可以使用我的功能