美文网首页
Swift menu菜单

Swift menu菜单

作者: 光光6 | 来源:发表于2021-06-01 23:47 被阅读0次

    /*功能: 只需要传入菜单箭头点位置、菜单宽度、数据源即可。

       1、支持任意点弹出(点是基于整个屏幕位置)

       2、会根据点位置自动计算菜单位置

       3、背景色、文字等支持自定义设置

       4、菜单最大宽度=屏幕-边距    最大高度=屏幕高度一半

    */

    根据位置展示对应效果

    importUIKit

    //Mark: menu代理

    protocol SwiftPopMenuDelegate :NSObjectProtocol{

        func swiftPopMenuDidSelectIndex(index:Int)

    }

    public enum SwiftPopMenuConfigure {

        casePopMenuTextFont(UIFont)            //菜单文字字体

        casePopMenuTextColor(UIColor)          //菜单文字颜色

        case PopMenuBackgroudColor(UIColor)    //菜单背景色

        casepopMenuCornorRadius(CGFloat)            //菜单圆角

        casepopMenuItemHeight(CGFloat)          //菜单行高度

        case popMenuSplitLineColor(UIColor)    //菜单分割线颜色

        case popMenuIconLeftMargin(CGFloat)          //icon左间距

        casepopMenuMargin(CGFloat)              //菜单与屏幕边距

        casepopMenuAlpha(CGFloat)              //菜单背景透明度

    }

    class ZHGPopMenuView: UIView {

        //delegate

       weak var delegate : SwiftPopMenuDelegate?

       //block

       publicvardidSelectMenuBlock:((_index:Int)->Void)?

       let KScrW:CGFloat = UIScreen.main.bounds.size.width

       let KScrH:CGFloat = UIScreen.main.bounds.size.height

        ///*  -----------------------  外部参数 通过configure设置 ---------------------------- */

        //区域外背景透明度

        private var popMenuOutAlpha:CGFloat = 0.3

        //背景色

        private var popMenuBgColor:UIColor = UIColor.white

        //圆角弧度

        private var popMenuCornorRadius:CGFloat = 6

        //文字颜色

        private var popMenuTextColor:UIColor = UIColor.black

        //字体大小等

        privatevarpopMenuTextFont:UIFont=UIFont.systemFont(ofSize:17)

        //菜单高度

        private var popMenuItemHeight:CGFloat = 44.0

        //菜单分割线颜色

        privatevarpopMenuSplitLineColor:UIColor=UIColor(red:222/255.0, green:222/255.0, blue:222/255.0, alpha:0.5)

        //icon左间距

        private var popMenuIconLeftMargin:CGFloat = 15

        //菜单与屏幕边距

        private var popMenuMargin:CGFloat = 10

        ///*  -----------------------  外部参数 over------------------------------------------ */

        privatevararrowPoint:CGPoint=CGPoint.zero        //小箭头位置

        privatevararrowViewWidth:CGFloat=15              //三角箭头宽

        privatevararrowViewHeight:CGFloat=10              //三角箭头高

        privatevarpopData:[(icon:String,title:String)]!      //数据源

        static let cellID:String = "SwiftPopMenuCellID"

        private var myFrame:CGRect!    //tableview  frame

        privatevararrowView:UIView! =nil

        var tableView:UITableView! = nil

     ///  初始化菜单

     ///

     /// - Parameters:

     ///  - menuWidth: 菜单宽度

     ///  - arrow: 箭头位置是popmenu相对整个屏幕的位置

     ///  - datas: 数据源,icon允许传空,数据源没数据,不会显示菜单

     ///  - configure: 配置信息,可不传

        init(menuWidth:CGFloat,arrow:CGPoint,datas:[(icon:String,title:String)],configures:[SwiftPopMenuConfigure] = []) {

            super.init(frame:UIScreen.main.bounds)

            self.frame = UIScreen.main.bounds

            //读取配置

            configures.forEach{ (config)in

                switch(config){

                    caselet.PopMenuTextFont(value):

                        popMenuTextFont= value

                    caselet.PopMenuTextColor(value):

                        popMenuTextColor= value

                    caselet.PopMenuBackgroudColor(value):

                        popMenuBgColor= value

                    caselet.popMenuCornorRadius(value):

                        popMenuCornorRadius= value

                    caselet.popMenuItemHeight(value):

                        popMenuItemHeight= value

                    caselet.popMenuSplitLineColor(value):

                        popMenuSplitLineColor= value

                    caselet.popMenuIconLeftMargin(value):

                        popMenuIconLeftMargin= value

                    caselet.popMenuMargin(value):

                        popMenuMargin= value

                    caselet.popMenuAlpha(value):

                        popMenuOutAlpha= value

                }

            }

            popData= datas

            //设置myFrame size  ,original会在后面计算

            myFrame=CGRect(x:0, y:0, width: menuWidth, height:popMenuItemHeight*CGFloat(popData.count))

            myFrame.size.height = min(KScrH/2, myFrame.height)

            myFrame.size.width = min(KScrW-popMenuMargin*2, myFrame.width)

            //设置肩头,与屏幕间隔10

            arrowPoint= arrow

            arrowPoint.x = max(popMenuMargin, min(arrowPoint.x, KScrW-popMenuMargin))

        }

        requiredpublicinit?(coder aDecoder:NSCoder) {

            fatalError("init(coder:) has not been implemented")

        }

        funcinitViews() {

            self.backgroundColor = UIColor.black.withAlphaComponent(popMenuOutAlpha)

            letarrowPs =getArrowPoints()

            myFrame.origin= arrowPs.3

            letisarrowUP = arrowPs.4

            print(arrowPs)

            //箭头

            arrowView=UIView(frame: CGRect(x: myFrame.origin.x, y: isarrowUP ? myFrame.origin.y-arrowViewHeight : myFrame.origin.y+myFrame.height, width: myFrame.width, height: arrowViewHeight))

            letlayer=CAShapeLayer()

            letpath=UIBezierPath()

            path.move(to: arrowPs.0)

            path.addLine(to: arrowPs.1)

            path.addLine(to: arrowPs.2)

            layer.path=path.cgPath

            layer.fillColor=popMenuBgColor.cgColor

            arrowView.layer.addSublayer(layer)

            self.addSubview(arrowView)

            tableView=UITableView(frame:CGRect(x:myFrame.origin.x,y:myFrame.origin.y,width:myFrame.width,height:myFrame.height), style: .plain)

            tableView.register(SwiftPopMenuCell.classForCoder(), forCellReuseIdentifier:ZHGPopMenuView.cellID)

            tableView.backgroundColor = popMenuBgColor

            tableView.layer.cornerRadius = popMenuCornorRadius

            tableView.separatorStyle = .none

            tableView.layer.masksToBounds = true

            tableView.delegate=self

            tableView.dataSource=self

            tableView.bounces=false

            UIView.animate(withDuration:0.3) {

                self.addSubview(self.tableView)

            }

        }

        /// 计算箭头位置

        ///

        /// - Returns: (三角箭头顶,三角箭头左,三角箭头右,tableview 原点,是否箭头朝上)

        func getArrowPoints() -> (CGPoint,CGPoint,CGPoint,CGPoint,Bool) {

            if arrowPoint.x <= popMenuMargin {

                arrowPoint.x = popMenuMargin

            }

            if arrowPoint.x >= KScrW - popMenuMargin{

                arrowPoint.x = KScrW - popMenuMargin

            }

            varoriginalPoint =CGPoint.zero

            //箭头中间距离左边距离

            vararrowMargin:CGFloat=popMenuMargin

            if arrowPoint.x < KScrW/2{

                if(arrowPoint.x>myFrame.width/2) {

                    arrowMargin =myFrame.width/2

                    originalPoint =CGPoint(x:arrowPoint.x-myFrame.width/2, y:arrowPoint.y+arrowViewHeight)

                }else{

                    arrowMargin =arrowPoint.x-popMenuMargin

                    originalPoint =CGPoint(x:popMenuMargin, y:arrowPoint.y+arrowViewHeight)

                }

            }else{

                if (KScrW-arrowPoint.x) < myFrame.width/2{

                    arrowMargin = (myFrame.width-KScrW+arrowPoint.x)

                    originalPoint =CGPoint(x: KScrW-popMenuMargin-myFrame.width, y: arrowPoint.y+arrowViewHeight)

                }else{

                    arrowMargin =myFrame.width/2

                    originalPoint =CGPoint(x:arrowPoint.x-myFrame.width/2, y:arrowPoint.y+arrowViewHeight)

                }

            }

            //箭头朝上

            if (KScrH - arrowPoint.y) > myFrame.height{

                return(CGPoint(x: arrowMargin, y:0),CGPoint(x: arrowMargin-arrowViewWidth/2, y:arrowViewHeight),CGPoint(x: arrowMargin+arrowViewWidth/2, y:arrowViewHeight),originalPoint,true)

            }else{

                originalPoint.y = arrowPoint.y-myFrame.height-arrowViewHeight

                return(CGPoint(x: arrowMargin, y:arrowViewHeight),CGPoint(x: arrowMargin-arrowViewWidth/2, y:0),CGPoint(x: arrowMargin+arrowViewWidth/2, y:0),originalPoint,false)

            }

        }

    }

    // MARK: - 页面显示、隐藏

    extension ZHGPopMenuView{

        overridepublicfunctouchesBegan(_touches:Set, with event:UIEvent?) {

            iftouches.first?.view!=tableView{

                dismiss()

            }

        }

        publicfuncshow() {

            ifpopData.isEmpty{

                return

            }

            initViews()

            UIApplication.shared.keyWindow?.addSubview(self)

        }

        publicfuncdismiss() {

            self.removeFromSuperview()

        }

    }

    // MARK: - UITableViewDataSource,UITableViewDelegate

    extension ZHGPopMenuView : UITableViewDataSource,UITableViewDelegate{

        publicfunctableView(_tableView:UITableView, numberOfRowsInSection section:Int) ->Int{

            returnpopData.count

        }

        publicfunctableView(_tableView:UITableView, cellForRowAt indexPath:IndexPath) ->UITableViewCell{

            ifpopData.count>indexPath.row{

                letcell = tableView.dequeueReusableCell(withIdentifier:ZHGPopMenuView.cellID)as!SwiftPopMenuCell

                letmodel =popData[indexPath.row]

                cell.setConfig(_txtColor: popMenuTextColor, _lineColor: popMenuSplitLineColor, _txtFont: popMenuTextFont, _iconLeft: popMenuIconLeftMargin)

                ifindexPath.row==popData.count-1{

                    cell.fill(iconName: model.icon, title: model.title, islast:true)

                }else{

                     cell.fill(iconName: model.icon, title: model.title)

                }

                returncell

            }

            return UITableViewCell()

        }

        publicfunctableView(_tableView:UITableView, heightForRowAt indexPath:IndexPath) ->CGFloat{

            return popMenuItemHeight

        }

        publicfunctableView(_tableView:UITableView, heightForFooterInSection section:Int) ->CGFloat{

            return0.01

        }

        publicfunctableView(_tableView:UITableView, didSelectRowAt indexPath:IndexPath) {

            ifself.delegate!=nil{

                self.delegate?.swiftPopMenuDidSelectIndex(index: indexPath.row)

            }

            if didSelectMenuBlock != nil {

                didSelectMenuBlock!(indexPath.row)

            }

            dismiss()

        }

    }

    /// UITableViewCell

    class SwiftPopMenuCell: UITableViewCell {

        var iconImage:UIImageView!

        var lblTitle:UILabel!

        varline:UIView!

        //自定义属性

        varlineColor:UIColor=UIColor(red:222/255.0, green:222/255.0, blue:222/255.0, alpha:0.5)

        var txtColor:UIColor = UIColor.black

        vartxtFont:UIFont=UIFont.systemFont(ofSize:17)

        variconLeft:CGFloat=15

        overrideinit(style:UITableViewCell.CellStyle, reuseIdentifier:String?) {

            super.init(style: style, reuseIdentifier: reuseIdentifier)

            self.backgroundColor = UIColor.clear

            iconImage=UIImageView()

            self.contentView.addSubview(iconImage)

            self.selectionStyle = .none

            lblTitle=UILabel()

            self.contentView.addSubview(lblTitle)

            line=UIView()

            self.contentView.addSubview(line)

        }

        requiredinit?(coder aDecoder:NSCoder) {

            fatalError("init(coder:) has not been implemented")

        }

        funcfill(iconName:String,title:String,islast:Bool=false) {

            iconImage.image=UIImage(named: iconName)

            lblTitle.text= title

            line.isHidden= islast

        }

        funcsetConfig(_txtColor:UIColor,_lineColor:UIColor,_txtFont:UIFont,_iconLeft:CGFloat) {

            txtColor= _txtColor

            txtFont= _txtFont

            lineColor= _lineColor

            iconLeft= _iconLeft

            line.backgroundColor = lineColor

            lblTitle.textColor = txtColor

            lblTitle.font = txtFont

        }

        override func layoutSubviews() {

            super.layoutSubviews()

            self.iconImage.frame=CGRect(x:iconLeft, y: (self.bounds.size.height-20)/2, width:20, height:20)

            self.lblTitle.frame=CGRect(x:20+iconLeft*2, y:0, width:self.bounds.size.width-40, height:self.bounds.size.height)

            self.line.frame=CGRect(x:0, y:self.frame.size.height-1, width:self.frame.size.width, height:1)

        }

    }

    相关文章

      网友评论

          本文标题:Swift menu菜单

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