效果图:
废话不多说,直接上代码:
import UIKit
//代理方法,选中事件
protocol POPMenuViewDelegate {
func POPMenuViewDidSelectedAt(index:Int)
}
enum POPMenueDirection {
case left
case right
}
class POPMenuView: UIView{
var delegate:POPMenuViewDelegate?
var font:UIFont = Font.largeP
var direction:POPMenueDirection = POPMenueDirection.left
var menuArr:[PopMenu] = [PopMenu](){
didSet{
self.tableView.reloadData()
}
}
var orign:CGPoint = CGPoint.zero
var cellHeight:CGFloat = 44
//分割线颜色
var separtorColor:UIColor = Color.line2
var textColor:UIColor = Color.textM
//背景颜色
var bgColor:UIColor = Color.mainBg{
didSet{
self.tableView.backgroundColor = bgColor
}
}
lazy var tableView:UITableView = {
let tabV = UITableView(frame: CGRect.zero, style: .plain)
tabV.backgroundColor = UIColor.white
tabV.bounces = false
tabV.layer.cornerRadius = 5
tabV.delegate = self
tabV.dataSource = self
tabV.register(POPMenuViewCell.self, forCellReuseIdentifier: "menuCell")
return tabV
}()
private override init(frame: CGRect) {
super.init(frame: frame)
}
func InitUI(){
self.addSubview(self.tableView)
tableView.tableFooterView = UIView()
}
//创建
static func initWith(dataArray:[PopMenu], origin:CGPoint, size:CGSize, direction:POPMenueDirection) -> POPMenuView{
let menuView = POPMenuView(frame: CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: SCREEN_HEIGHT))
menuView.direction = direction
menuView.orign = origin
menuView.cellHeight = size.height
menuView.backgroundColor = UIColor(white: 0.3, alpha: 0.2)
if direction == POPMenueDirection.left {
menuView.tableView.frame = CGRectMake(origin.x, origin.y, size.width, size.height*CGFloat(dataArray.count))
}else{
menuView.tableView.frame = CGRectMake(origin.x, origin.y, -size.width, size.height*CGFloat(dataArray.count))
}
menuView.InitUI()
menuView.menuArr = dataArray
menuView.pop()
return menuView
}
func pop(){
let window = UIApplication.shared.keyWindow
window?.addSubview(self)
let frame = self.tableView.frame
self.tableView.frame = CGRect(x: orign.x, y: orign.y, width: 0, height: 0)
SPAnimation.animate(0.2, animations: {
self.tableView.frame = frame
})
}
func dismiss(){
UIView.animate(withDuration: 0.2, animations: {
self.tableView.frame = CGRect(x: self.orign.x, y: self.orign.y, width: 0, height: 0)
}) { (finished) in
self.removeFromSuperview()
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
dismiss()
}
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
context?.beginPath()
if self.direction == POPMenueDirection.left {
let startX = self.orign.x + 20
let startY = self.orign.y
context?.move(to: CGPoint(x: startX, y: startY))//起点
context?.addLine(to: CGPoint(x: startX+5, y: startY-8))
context?.addLine(to: CGPoint(x: startX+10, y: startY))
}else{
let startX = self.orign.x - 20
let startY = self.orign.y
context?.move(to: CGPoint(x: startX, y: startY))//起点
context?.addLine(to: CGPoint(x: startX+5, y: startY-8))
context?.addLine(to: CGPoint(x: startX+10, y: startY))
}
context?.closePath()//结束
self.tableView.backgroundColor?.setFill()//设置填充色
self.tableView.backgroundColor?.setStroke()
context?.drawPath(using: .fillStroke)//绘制路径
}
}
extension POPMenuView:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.menuArr.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return self.cellHeight
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "menuCell", for: indexPath) as! POPMenuViewCell
let menu = self.menuArr[indexPath.row]
cell.imgView.image = UIImage(named: menu.icon)
cell.titleLabel.text = menu.title
cell.titleLabel.font = font
cell.titleLabel.textColor = textColor
cell.separtorLine.isHidden = (indexPath.row < menuArr.count - 1) ? false : true
cell.separtorLine.backgroundColor = separtorColor
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
self.delegate?.POPMenuViewDidSelectedAt(index: indexPath.row)
}
}
自定义cell,不知道为啥,这里的分割线显示不出来,于是我自定义了一条分割线
class POPMenuViewCell: UITableViewCell {
lazy var imgView:UIImageView = UIImageView()
lazy var titleLabel:UILabel = UILabel()
lazy var separtorLine:UIView = UIView()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
titleLabel.textColor = Color.textM
titleLabel.textAlignment = .center
self.backgroundColor = UIColor.clear
self.contentView.addSubview(self.imgView)
self.contentView.addSubview(self.titleLabel)
self.contentView.addSubview(self.separtorLine)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
self.imgView.snp.makeConstraints { (make) in
make.top.bottom.equalToSuperview().inset(8)
make.left.equalToSuperview().inset(10)
make.width.equalTo(self.imgView.snp.height)
}
self.titleLabel.snp.makeConstraints { (make) in
make.left.equalTo(self.imgView.snp.right)
make.top.bottom.equalToSuperview().inset(5)
make.right.equalToSuperview().inset(5)
}
self.separtorLine.snp.makeConstraints { (make) in
make.bottom.equalToSuperview()
make.left.right.equalToSuperview().inset(10)
make.height.equalTo(1)
}
}
}
struct PopMenu {
var icon:String
var title:String
init(icon:String, title:String) {
self.icon = icon
self.title = title
}
}
使用方法很简单:
//数组用于添加菜单选项
lazy var menuArr:[PopMenu] = [PopMenu]()
lazy var menuView:POPMenuView = POPMenuView()
func createMenuArr(){
self.menuArr.append(PopMenu(icon: "中石化", title: "充值记录"))
self.menuArr.append(PopMenu(icon: "中石化", title: "我的油卡"))
self.menuArr.append(PopMenu(icon: "中石化", title: "申请油卡"))
}
点击事件,显示菜单
//显示菜单
func showRightMenu(btn:UIButton){
menuView = POPMenuView.initWith(dataArray: self.menuArr, origin: CGPoint.init(x: SCREEN_WIDTH-10, y: 75), size: CGSize.init(width: 130, height: 44), direction: POPMenueDirection.right)
menuView.delegate = self
menuView.pop()
}
//MARK: 菜单选项的代理方法
func POPMenuViewDidSelectedAt(index: Int) {
print("点击了第\(index)个")
switch index {
case 0: break
case 1: break
case 2:
let to_v = OilCardApplyViewController()
self.pushHideBottomBar(to_v, animated: true)
//隐藏
menuView.dismiss()
break
default: break
}
}