Swift点击区域弹出选择气泡

2019-05-07  本文已影响0人  XC1988
WechatIMG3.jpeg
import UIKit
protocol ZYCSelectViewDelegate:class {
    func selectOption(num:Int)->Void
}
class ZYCSelectView: UIView {
  private weak var delegate:ZYCSelectViewDelegate?
  private var buttonHeight:CGFloat = 50
  private weak var mainView:UIView?
  private var mainViewWidth:CGFloat?
  private var isShowRect:Bool?


  var stringArray:[String]?{
      didSet{
          for item in self.mainView?.subviews ?? []{
              item.removeFromSuperview()
          }
          let array:[String] = stringArray ?? []
          let viewHeight:CGFloat = buttonHeight*CGFloat(array.count)
          let viewWidth:CGFloat = mainViewWidth ?? 0
          mainView?.frame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight+10)
          mainView?.createBubbleView(radius: 4,isShowRect:isShowRect ?? false)
        
          for (index,item) in array.enumerated(){
              let button:UIButton = UIButton(frame:CGRect(x: 0, y:buttonHeight*CGFloat(index)+10, width: viewWidth, height: buttonHeight))
              button.tag = 100+index
              button.setTitle(item, for: .normal)
              button.titleLabel?.font = adapterFont(font: 14)
              button.setTitleColor(UIColor.grayValue(value: 47), for: .normal)
              button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
              mainView?.addSubview(button)
              if index != array.count - 1{
                  let line:UIView = UIView(frame: CGRect(x: 10, y: buttonHeight*CGFloat(index+1)+10, width: viewWidth-20, height: 1))
                  line.backgroundColor = UIColor.grayValue(value: 248)
                  mainView?.addSubview(line)
              }
          }
      }
  }

  var imagesAndTitles:[(String,String)]?{
      didSet{
          for item in self.mainView?.subviews ?? []{
              item.removeFromSuperview()
          }
          let array:[(String,String)] = imagesAndTitles ?? []
          let viewHeight:CGFloat = buttonHeight*CGFloat(array.count)
          let viewWidth:CGFloat = mainViewWidth ?? 0
          mainView?.frame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight+10)
          mainView?.createBubbleView(radius: 4,isShowRect:isShowRect ?? false)
        
        
          for (index,item) in array.enumerated(){
              let button:UIButton = UIButton(frame:CGRect(x: 0, y:buttonHeight*CGFloat(index)+10, width: viewWidth, height: buttonHeight))
              button.titleLabel?.textAlignment = .center
              button.tag = 100+index
              button.titleLabel?.font = adapterFont(font: 14)
              button.setTitle("   \(item.1)", for: .normal)
              button.setImage(UIImage(named: item.0), for: UIControl.State.normal)
              button.setTitleColor(UIColor.grayValue(value: 47), for: .normal)
              button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
              mainView?.addSubview(button)
              if index != array.count - 1{
                  let line:UIView = UIView(frame: CGRect(x: 10, y: buttonHeight*CGFloat(index+1)+10, width: viewWidth-20, height: 1))
                  line.backgroundColor = UIColor.grayValue(value: 248)
                  mainView?.addSubview(line)
              }
          }
      }
  }

  required init?(coder aDecoder: NSCoder) {
      fatalError("init(coder:) has not been implemented")
  }
  init(view:ZYCSelectViewDelegate,width:CGFloat = 120,buttonHeight:CGFloat = 50,isShowRect:Bool = true) {
      super.init(frame:CGRect.zero)
      self.delegate = view
      self.mainViewWidth = width
      self.buttonHeight = buttonHeight
      self.isShowRect = isShowRect
      KEY_WINDOW.addSubview(self)
      self.frame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: SCREEN_HEIGHT)
      self.isHidden = true
      createUI()
  }
  private func createUI(){
      let backView:UIView = UIView(frame: CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: SCREEN_HEIGHT))
      backView.isUserInteractionEnabled = true
      backView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(backTap)))
      backView.backgroundColor = .black
      backView.alpha = 0.3
      self.insertSubview(backView, at: 0)
    
      let mainView:UIView = UIView()
      mainView.isUserInteractionEnabled = true
      self.addSubview(mainView)
      self.mainView = mainView
  }

  @objc private func buttonAction(sender:UIButton){
      delegate?.selectOption(num: sender.tag%100)
      hide()
  }
  @objc private func backTap(){
      hide()
  }
  private func hide(){
      self.isHidden = true
      self.removeFromSuperview()
  }
  func show(view:UIView){
      //获取视图在keywindow的位置
      let rect:CGRect = view.convert(view.bounds, to: KEY_WINDOW)
      mainView?.left = rect.origin.x+rect.size.width-(mainViewWidth ?? 0)-8
      mainView?.top = rect.origin.y+rect.size.height-5
      self.isHidden = false
  }

}

///这部分才是重点,主要是贝塞尔曲线画气泡

  extension UIView{
      func createBubbleView(radius:CGFloat,backGroundColor:UIColor =     UIColor.white,isShowRect:Bool = true){
          let pai:CGFloat = CGFloat(Double.pi)
          let width:CGFloat = self.width
         let linePath = UIBezierPath(arcCenter: CGPoint(x: radius, y: 10+radius), radius: radius, startAngle: pai*1.5, endAngle: pai, clockwise: false)
         linePath.addArc(withCenter: CGPoint(x: radius, y: self.height-radius), radius: radius, startAngle: pai, endAngle: pai*0.5, clockwise: false)
         linePath.addArc(withCenter: CGPoint(x: self.width - radius, y: self.height-radius), radius: radius, startAngle: pai*0.5, endAngle: 0, clockwise: false)
         linePath.addArc(withCenter: CGPoint(x: self.width - radius, y: 10+radius), radius: radius, startAngle: 0, endAngle: pai*1.5, clockwise: false)
         if isShowRect{
             let right:CGFloat = radius > 10 ? radius+2 : 12
             linePath.addLine(to: CGPoint(x: width-right, y: 10))
             linePath.addLine(to: CGPoint(x: width-right-5, y: 0))
             linePath.addLine(to: CGPoint(x: width-right-10, y: 10))
    }
         linePath.close()
         //设施路径画布
         let lineShape = CAShapeLayer()
         lineShape.frame = CGRect(x: 0, y: 0, width: self.width, height: self.height)
         //获取贝塞尔曲线的路径
         lineShape.path = linePath.cgPath
         //填充色
         lineShape.fillColor = backGroundColor.cgColor
         //把绘制的图放到layer上
         self.layer.addSublayer(lineShape)
     }
 }

具体使用:

        let view:ZYCSelectView = ZYCSelectView(view:self)    //协议绑定控制器
        view.imagesAndTitles = [("issuelog","日志"),("issuefollowUp","跟进"),("issueall","全部")]
        view.show(view: sender)

协议回调

    func selectOption(num: Int) {
    //do something

}

上一篇 下一篇

猜你喜欢

热点阅读