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()