美文网首页Swift学习
Swift struct + protocol 优雅的扩展方式

Swift struct + protocol 优雅的扩展方式

作者: 小点草 | 来源:发表于2020-09-06 17:01 被阅读0次

    前言

    很多时候,系统库以及一些第三方库,调用起来太麻烦,比如给一个View设置阴影,需要写几行代码:

    view.layer.shadowColor = UIColor.red.cgcolor
    view.layer.shadowOffset = .zero
    view.layer.shadowOpacity = 0.5
    view.layer.shadowRadius = 2
    

    如果每个view都写这样的代码,就会显得很傻,很臃肿,所以我们一般都会给UIView扩展出一个方法:

    extension UIView{
        func setShadow(_ color: UIColor?,
            offset: CGSize,opacity: Float,radius: CGFloat){
            layer.shadowColor = color?.cgColor
            layer.shadowOffset = offset
            layer.shadowOpacity = opacity
            layer.shadowRadius = radius
        }
    }
    

    这样每次设置阴影就调用这个方法就可以了。

    但是,有时候一些第三方库,或者项目的其他开发人员在UIVIew也扩展了一个叫setShadow的方法,而且参数完全一样,只是方法的内容并不同,效果也不是你想要的,这时你又不想换另一种可能引起歧义的方法名,这时你就可以使用struct + protocol 的扩展方式。

    一、创建项目或自己的专属extension类

    struct + protocol的扩展方式是swift泛型的一个灵活运用,很多优秀的第三方库(如RxSwiftKingfisher)都使用了这种扩展方式,这种方式最大的优点是可以避免和其他库的冲突,还有些其他的优点如管理方便只是附加的。

    下面是实现代码:

    struct TestExtension<TE> {
        let base : TE
        init(_ base: TE) {
            self.base = base
        }
    }
    
    protocol TestExtensionCompatible {
        associatedtype Compatible
        var te : TestExtension<Compatible> { get }
        static var te : TestExtension<Compatible>.Type { get }
    }
    
    extension TestExtensionCompatible {
        var te : TestExtension<Self> {
            return TestExtension(self)
        }
        
        static
        var te : TestExtension<Self>.Type {
            return TestExtension<Self>.self
        }
        
    }
    

    简单的几行代码就建立了一个属于项目或自己的扩展类,下面我们利用这个类去扩展UIView的阴影设置。

    二、扩展UIView

    直接上代码:

    extension UIView : TestExtensionCompatible{}
    extension TestExtension where TE : UIView{
        
        func setShadow(_ color: UIColor?,
                       offset: CGSize,
                       opacity: CGFloat,
                       radius: CGFloat) {
            base.layer.shadowColor = color?.cgColor
            base.layer.shadowOffset = offset
            base.layer.shadowOpacity = Float(opacity)
            base.layer.shadowRadius = radius
        }
    }
    

    首先给UIView继承协议 TestExtensionCompatible,然后在TestExtension的扩展里实现setShadow的方法,注意where TE : UIView这里,也可以是TE == UIVIew,用“ == ”会限制了扩展里的方法只能给UIVIew使用,而用“:”的话UIVIew的子类也可以使用扩展里的方法。

    调用:

    let view = UIView()
    view.te.setShadow(.black, offset: .zero, opacity: 0.5, radius: 2)
    

    总结

    struct + protocol的扩展不但使代码变得更优雅,避免和其他库的代码冲突,而且对代码管理,以及移植到其他项目使用更加方便。所以如果要扩展一些功能,十分推荐使用这种方式

    相关文章

      网友评论

        本文标题:Swift struct + protocol 优雅的扩展方式

        本文链接:https://www.haomeiwen.com/subject/vdbcektx.html