iOS 一个弹框的封装

1.背景

最近在研究设计模式,刚好公司需求又加了弹框,以前封装的虽然能满足,但是耦合度太高,改动的地方太多,所以就萌生了自己写一个符合设计模式,封装与拓展性都比之前好的弹框。

2.思路

  • 将弹框分为三个部分,标题,内容与交互按钮
  • 运用抽象工厂模式生成两类产品,文字显示的item(标题,和内容文本都属于这个)和用于交互的item(按钮)
  • 再用构造者模式(虽说是建造者模式,但因为建造方式单一,就省略了指挥者和抽象建造类,只有具体产品类和具体建造者类,所以叫它构造者模式)组装各个产品部分形成弹框类
  • 各种自定义设置也通过链式调用灵活提供给调用者(这里面用到的也是构造者模式)

3.优点

  • 高度封装,外部调用只知道工厂类和建造者类,不用管弹框内部怎么实现的,怎么整合的
  • 高度拓展,要是不太满意现有的item,可以自行基于工厂模式添加抽象产品和具体产品类,以供拓展,耦合度低,嵌入性小。
  • 动画效果灵活,可自行选择显示与隐藏的动画。

4.部分源码

具体源码请参考GitHub

LYAlertFactoryProtocol

//抽象工厂
public protocol LYAlertFactoryProtocol {
      func creatAlertShowItem(_ type:LYAlertTitleItemType, _ text:String) -> LYAlertTitleShowProtocol
     func creatAlertInteractiveItem(_ text: String)->LYAlertInteractiveItemProtocol
}
//抽象产品基类
public protocol LYAlertItemProtocol{
     func titleColor(_ color:UIColor) -> Self
     func fontSize(_ font:CGFloat) -> Self
     func attribute(_ attribute:[NSAttributedString.Key :Any])->Self
}
//抽象文字显示产品
public protocol LYAlertTitleShowProtocol:LYAlertItemProtocol {
      func line(_ color:UIColor,_ width:CGFloat) -> Self
     func textAlignment(_ alignment:NSTextAlignment) -> Self
    
}
//抽象交互产品
public protocol LYAlertInteractiveItemProtocol:LYAlertItemProtocol  {
      func btnBackgroundColor(_ color:UIColor) -> Self
      func itemBackgroundColor(_ color:UIColor) -> Self
      func btnRadius(_ radius:CGFloat) -> Self
      func btnBorderWidth(_ borderWidth:CGFloat) -> Self
      func btnBorderColor(_ color:UIColor) -> Self
      func line(_ color:UIColor,_ width:CGFloat,_ type:LYLineType) -> Self
      func btnHeight(_ height:CGFloat)->Self
      func btnMarin(_ marin:CGFloat)->Self

     func action(clo:@escaping LYCommonSet.btnClosure)  -> Self
}

LYAlertFactory

//具体工厂类
public class  LYAlertFactory:LYAlertFactoryProtocol{
    public init() {}

    //创建展示 item
   public func creatAlertShowItem(_ type: LYAlertTitleItemType, _ text: String) -> LYAlertTitleShowProtocol {
     return LYAlertTitleItem.init(type, text: text)
    }
    //创建交互 item
    public func creatAlertInteractiveItem(_ text: String) -> LYAlertInteractiveItemProtocol {
        return LYAlertInteractiveItem.init(text)
   
    }
}

LYAlertBuilder

public class LYAlertBuilder {
    var alertView:LYAlertShowView?
    
   public init(_ title:LYAlertTitleShowProtocol?,_ content:LYAlertTitleShowProtocol,_ buttons:[LYAlertInteractiveItemProtocol]) {
        alertView = LYAlertShowView.init(title, content, buttons)
    }
    
   public func borderColor(_ color:UIColor) -> Self {
        self.alertView?.alertView.layer.borderColor = color.cgColor
        return self
    }
    public func borderWidth(_ width:CGFloat) -> Self {
        self.alertView?.alertView.layer.borderWidth = width
        return self
    }
    public func cornerRadius(_ radius:CGFloat) -> Self {
        self.alertView?.alertView.layer.cornerRadius = radius
        return self
    }
    public func shadowPath(_ path:CGPath) -> Self {
        self.alertView?.alertView.layer.shadowPath = path
        return self
    }
    public  func shadowOffset(_ size:CGSize) -> Self {
        self.alertView?.alertView.layer.shadowOffset = size
        return self
    }
    public func shadowRadius(_ radius:CGFloat) -> Self {
        self.alertView?.alertView.layer.shadowRadius = radius
        return self
    }
    public func shadowOpacity(_ opacity:Float) -> Self {
        self.alertView?.alertView.layer.shadowOpacity = opacity
        return self
    }
    public func shadowColor(_ color:UIColor) -> Self {
        self.alertView?.alertView.layer.shadowColor = color.cgColor
        return self
    }
    public func maskAlpha(_ alpha:CGFloat) -> Self {
        self.alertView?.blackView.backgroundColor = LYCommonSet.RGBA(r: 0, g: 0, b: 0, a: alpha)
        return self
    }
    public func showAnimation(_ type:LYAlertAnimationPopType,_ during:CFTimeInterval)->Self{
        self.alertView?.showType = type
        self.alertView?.showDuring = during
        return self
    }
    public func hideAnimation(_ type:LYAlertAnimationDissType,_ during:CFTimeInterval)->Self{
        self.alertView?.hideType = type
        self.alertView?.hideDuring = during
        return self
    }
    
    public func build()-> LYAlertShowView?{
       return alertView
    }
    
}

4.安装

方式一:使用CocoaPods

pod 'LYAlertView'

方式二:手动导入

  • LYAlertView文件夹中的所有源代码拽入项目中
  • 直接调用

5.调用示例

            let item1 = LYAlertFactory()
                .creatAlertShowItem(.title, "温馨提示")
                .fontSize(17)
                .titleColor(UIColor.darkGray)
            let item2 = LYAlertFactory()
                .creatAlertShowItem(.content, "是否确认向老师发起一对一错题辅导请求?")
                .fontSize(16)
                .titleColor(UIColor.darkGray)
                .line(UIColor.lightGray, 0.5)
            let item3 = LYAlertFactory()
                .creatAlertInteractiveItem("我再想想")
                .fontSize(15)
                .btnHeight(30)
                .btnMarin(10)
                .titleColor(UIColor.gray)
                .line(UIColor.lightGray, 0.5, .left)
                .action {
                     print("我再想想")
                }
            let item4 = LYAlertFactory()
                .creatAlertInteractiveItem("确认发起")
                .fontSize(15)
                .btnHeight(30)
                .btnMarin(10)
                .titleColor(UIColor.brown)
                .line(UIColor.lightGray, 0.5, .left)
                .action {
                    print("确认发起")
                }
 let alert = LYAlertBuilder.init(item1, item2, [item3,item4])
                .cornerRadius(15)
                .maskAlpha(0.6)
                .showAnimation(.shakeFromTop, 0.5)
                .hideAnimation(.shakeToTop, 0.5)
                .build()
  alert?.show()

6.效果展示

1

2

3

4

你可能感兴趣的:(iOS 一个弹框的封装)