Swift.小型弹出列表菜单
2018-10-22 本文已影响17人
王四猫
效果图
实现效果:
点击弹出小型列表菜单.
view.frame,初始位置等都可通过调用方法自定制.
实现cell数量自适应,当数量大于4时,view高度固定,可滑动.
cell实现纯文字与icon+文字两种状态.自适应.
通过回调响应点击方法.
点任意位置菜单消失.
实现思路:
本质上这个弹出菜单是一个tableView.
所以我们实现的是一个弹出一个背景透明的全屏View,其中包含一个小tableView.
实现方式:
1.创建弹出View,并添加tableView.
2.使用drawRect方法,添加tableView上的小三角形.
3.创建menuCell,使其实现纯文字,icon+文字两种type
4.创建EWPopMenu类,留出外部方法方便调用
1.创建弹出View,并添加tableView.
/// init
///
/// - Parameters:
/// - width: tableView.width
/// - height: tableView最大height,如果cell数量大于4,则是tableView.frame.size.height
/// - point: 初始点,tableView上的三角形的顶点
/// - items: 每个cell的title数组
/// - imgSource: 每个cell的icon数组,可为空
/// - action: 回调方法
init(width: CGFloat, height: CGFloat, point: CGPoint, items: [String], imgSource: [String], action: ((Int) -> ())?){
super.init(frame:CGRect(x: 0, y: 0, width: ScreenInfo.Width, height: ScreenInfo.Height))
drawMyTableView()
/// view全屏展示
self.frame = CGRect(x: 0, y: 0, width: ScreenInfo.Width, height: ScreenInfo.Height)
/// 获取起始点
self.point = CGPoint(x: point.x, y: ScreenInfo.navigationHeight + point.y)
/// tableView高度由init方法传入
self.layerWidth = width
self.titleSource.removeAll()
self.titleSource += items
self.imgSource.removeAll()
self.imgSource += imgSource
/// 如果图片数组与标题数组数量不符,则不展示图片
if imgSource.count != titleSource.count{
self.imgSource.removeAll()
}
/// 如果没有图片展示,则将tabelView宽度控制在100
if imgSource.count == 0{
self.layerWidth = 100
}
/// 弱引用防止闭包循环引用
weak var weakSelf = self
if action != nil{
weakSelf?.indexBlock = { row in
/// 点击cell回调,将点击cell.indexpath.row返回
action!(row)
}
}
/// tableView高度,如果大于4个则为4个itemHeight,使tableView可滑动,如果小于4个则动态显示
self.layerHeight = titleSource.count > 4 ? height : CGFloat(CGFloat(items.count) * itemHeight)
self.addSubview(self.tableView)
/// 将tableView.frame更新,使其在展示正确效果
let y1 = (self.point?.y)! + 10
let x2 = (self.point?.x)! - self.layerWidth! + 20
tableView.frame = CGRect(x: x2, y: y1, width: self.layerWidth!, height: self.layerHeight!)
self.backgroundColor = UIColor.clear
}
extension EWPopMenuView:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return itemHeight
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.titleSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: EWMenuTableViewCell.identifier) as? EWMenuTableViewCell else {
return EWMenuTableViewCell()
}
cell.setContentBy(titArray: self.titleSource, imgArray: self.imgSource, row: indexPath.row)
cell.conLabel.text = self.titleSource[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.indexBlock!(indexPath.row)
}
}
2.使用drawRect方法,添加tableView上的小三角形.
/// drawRect方法,画tableView上的小三角形
override func draw(_ rect: CGRect) {
let y1 = (self.point?.y)! + 10
let x1 = (self.point?.x)! - 10
let x2 = (self.point?.x)! + 10
UIColor(white: 0, alpha: 0.66).set()
let context = UIGraphicsGetCurrentContext()
context?.beginPath()
context?.move(to: CGPoint(x: (self.point?.x)!, y: (self.point?.y)!))
context?.addLine(to: CGPoint(x: x1, y: y1))
context?.addLine(to: CGPoint(x: x2, y: y1))
context?.closePath()
context?.fillPath()
context?.drawPath(using: .stroke)
}
3.创建menuCell,使其实现纯文字,icon+文字两种type
public func setContentBy(titArray: [String], imgArray: [String], row: Int){
if imgArray.count == 0{
self.iconImg.isHidden = true
self.conLabel.frame = CGRect(x: kLineXY, y: 0, width: itemWidth - kLineXY * 2, height: itemHeight)
}else{
self.iconImg.isHidden = false
self.conLabel.frame = CGRect(x: self.iconImg.frame.maxX + kImgLabelWidth, y: 0, width: itemWidth - kImgLabelWidth - kLineXY - kImageWidth - 15 , height: itemHeight)
self.iconImg.image = UIImage(named: imgArray[row])
}
}
4.创建EWPopMenu类,留出外部方法方便调用
let NavigationMenuShared = EWPopMenu.shared
class EWPopMenu: NSObject {
static let shared = EWPopMenu()
private var menuView: EWPopMenuView?
public func showPopMenuSelecteWithFrameWidth(width: CGFloat, height: CGFloat, point: CGPoint, item: [String], imgSource: [String], action: @escaping ((Int) -> ())){
weak var weakSelf = self
/// 每次重置保证显示效果
if self.menuView != nil{
weakSelf?.hideMenu()
}
let window = UIApplication.shared.windows.first
self.menuView = EWPopMenuView(width: width, height: height, point: point, items: item, imgSource: imgSource, action: { (index) in
///点击回调
action(index)
weakSelf?.hideMenu()
})
menuView?.touchBlock = {
weakSelf?.hideMenu()
}
self.menuView?.backgroundColor = UIColor.black.withAlphaComponent(0)
window?.addSubview(self.menuView!)
}
public func hideMenu(){
self.menuView?.removeFromSuperview()
self.menuView = nil
}
}
使用方法:
将EWPopMenu文件夹拖入项目,调用时:
let items: [String] = ["测试1","测试2"]
let imgSource: [String] = ["test1","test2"]
NavigationMenuShared.showPopMenuSelecteWithFrameWidth(width: itemWidth, height: 160, point: CGPoint(x: ScreenInfo.Width - 30, y: 0), item: items, imgSource: imgSource) { (index) in
///点击回调
switch index{
case 0:
EWToast.showCenterWithText(text: "点击测试1")
case 1:
EWToast.showCenterWithText(text: "点击测试2")
default:
break
}
}
项目地址:EWPopMenu
有问题欢迎探讨.