iOS 自定义可拖拽 panel

自定义屏幕相关常量
import Foundation
import UIKit

struct JLScreen {
    
    static var width: CGFloat {
        return UIScreen.main.bounds.width
    }
    
    static var height: CGFloat {
        return UIScreen.main.bounds.height
    }
    
    static var status_navi_height: CGFloat {
        return UIApplication.shared.statusBarFrame.height + 44
    }
}

可以进一步封装, 将 tableVeiw 剥离出来

import UIKit

class JLPanel: UIView {

    enum JLPanelPosition {
        case bottom, middle, top
    }
       
    private let TOP_Y: CGFloat = JLScreen.status_navi_height + 20
    
    private let MIDDLE_Y: CGFloat = JLScreen.height * 0.5

    private let BOTTOM_Y: CGFloat = JLScreen.height

    private let threshold: CGFloat = 100
    
    var position: JLPanelPosition = .middle {
        didSet {
            if position == .top {
                self.tableView.isScrollEnabled = true
            } else {
                self.tableView.isScrollEnabled = false
            }
        }
    }
    
    lazy var tableView: UITableView = {
        let tableView = UITableView()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.isScrollEnabled = false
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        return tableView
    }()
    
    override init(frame: CGRect) {
        super.init(frame: CGRect(x: 0, y: MIDDLE_Y, width: JLScreen.width, height: JLScreen.height - TOP_Y))
        let panGesture: UIPanGestureRecognizer = UIPanGestureRecognizer()
        panGesture.delegate = self
        panGesture.addTarget(self, action: #selector(handlePanGesture(_:)))
        backgroundColor = .purple
        isUserInteractionEnabled = true
        layer.cornerRadius = 20
        layer.masksToBounds = true
        addGestureRecognizer(panGesture)
        addSubview(tableView)
        tableView.snp.makeConstraints { (make) in
            make.top.equalTo(30)
            make.left.right.bottom.equalToSuperview()
        }
    }
    
    @objc private func handlePanGesture(_ sender: UIPanGestureRecognizer) {
        let point = sender.translation(in: self)
        if sender.state == .began {
        } else if sender.state == .changed {
            if self.position == .top {
                if point.y > 0 {
                    self.frame.origin.y = TOP_Y + point.y
                }
            } else if self.position == .middle {
                if self.frame.origin.y >= TOP_Y {
                    self.frame.origin.y = self.MIDDLE_Y + point.y
                }
            } else if self.position == .bottom {
                
            }
        } else if sender.state == .ended {
            if self.position == .top {
                if point.y > self.MIDDLE_Y - self.TOP_Y {
                    UIView.animate(withDuration: 0.2) {
                        self.frame.origin.y = JLScreen.height
                    } completion: { (_) in
                        self.position = .bottom
                    }
                } else if point.y > threshold  {
                    UIView.animate(withDuration: 0.2) {
                        self.frame.origin.y = self.MIDDLE_Y
                    } completion: { (_) in
                        self.position = .middle
                    }
                } else {
                    UIView.animate(withDuration: 0.2) {
                        self.frame.origin.y = self.TOP_Y
                    } completion: { (_) in
                        self.position = .top
                    }
                }
            } else if self.position == .middle {
                if point.y > threshold {
                    UIView.animate(withDuration: 0.2) {
                        self.frame.origin.y = JLScreen.height
                    } completion: { (_) in
                        self.position = .bottom
                    }
                } else if point.y > 0 || point.y >= -threshold {
                    UIView.animate(withDuration: 0.2) {
                        self.frame.origin.y = self.MIDDLE_Y
                    } completion: { (_) in
                        self.position = .middle
                    }
                } else if point.y < -threshold {
                    UIView.animate(withDuration: 0.2) {
                        self.frame.origin.y = self.TOP_Y
                    } completion: { (_) in
                        self.position = .top
                    }
                }
            }
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}

extension JLPanel: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 25
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = "\(indexPath.row)"
        return cell
    }
}

extension JLPanel: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return false
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值