美文网首页
swift 类微信朋友圈九宫格拖拽图

swift 类微信朋友圈九宫格拖拽图

作者: 单抽律化娜 | 来源:发表于2020-03-11 15:39 被阅读0次
    import UIKit
    
    class MomentsViewController: UIViewController {
      
        private var vMoments: MomentsView!
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
            
            view.backgroundColor = .white
            
            vMoments = MomentsView()
    //        vMoments.rowCount = 4
    //        vMoments.maxCount = 7
            view.addSubview(vMoments)
            
            vMoments.snp.makeConstraints { (make) in
                make.left.equalTo(20)
                make.top.equalTo(100)
                make.right.equalTo(-20)
                make.height.equalTo(100)
            }
            
            /// 更新高度
            vMoments.heightBlock = { [weak self] height in
                self?.vMoments.snp.updateConstraints { (make) in
                    make.height.equalTo(height)
                }
            }
            
            /// 点击按钮
            vMoments.btnPostBlock = { [weak self] in
                self?.uploadImage()
            }
            
            /// 添加长按操作
            let gesture = UILongPressGestureRecognizer(target: self, action: #selector(longPress(_ :)))
            gesture.minimumPressDuration = 0.5
            view.addGestureRecognizer(gesture)
            
            /// 添加删除区域
            let vDeleteArea = MomentsDeleteView()
            vDeleteArea.isDelete = false
            view.addSubview(vDeleteArea)
            
            vDeleteArea.snp.makeConstraints { (make) in
                make.left.right.bottom.equalToSuperview()
                make.height.equalTo(60)
            }
            
            vDeleteArea.hideView()
            
            vMoments.vDeleteArea = vDeleteArea
        }
        
        /// 添加拖动手势
        @objc private func longPress(_ gesture: UILongPressGestureRecognizer) {
            vMoments.longPress(gesture)
        }
        
        func uploadImage() {
            vMoments.arrData.append(UIImage(named: "fengjingtu\(getRandom(1, 4))")!)
        }
        
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    
    class MomentsView: UIView, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
        
        /// collectionView
        private lazy var collectionView: UICollectionView = {
            
            let layout = UICollectionViewFlowLayout()
            layout.minimumLineSpacing = itemSpace
            layout.minimumInteritemSpacing = itemSpace
            
            let collectionView = UICollectionView(frame: frame, collectionViewLayout: layout)
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.backgroundColor = .clear
            collectionView.register(MomentsViewCell.self, forCellWithReuseIdentifier: "MomentsViewCell")
            addSubview(collectionView)
            
            return collectionView
        }()
        
        /// 上传按钮
        private lazy var btnPost: MomentsPostButton = {
            $0.addTarget(self, action: #selector(btnPostClick(_:)), for: .touchUpInside)
            $0.isHidden = true
            addSubview($0)
            return $0
        }(MomentsPostButton())
        
        /// 长按拖拽元素
        private lazy var dragingItem: UIImageView = {
            $0.contentMode = .scaleAspectFill
            $0.layer.masksToBounds = true
            superview?.insertSubview($0, aboveSubview: self)
            return $0
        }(UIImageView())
        
        /// 拖拽位置
        private var indexPath: IndexPath?
        
        /// 宽高
        private var itemLength: CGFloat = 0 {
            willSet {
                btnPost.snp.updateConstraints { (make) in
                    make.size.equalTo(CGSize(width: newValue, height: newValue))
                }
            }
            didSet {
                numberOfLines = 0
            }
        }
        
        /// 行数
        private var numberOfLines: Int = -1 {
            willSet {
                heightBlock?(itemLength + CGFloat(newValue) * (itemLength + itemSpace))
            }
        }
        
        /// 是否能删除
        private var canDelete: Bool = false
        
        /// 最大个数
        var maxCount: Int = 9
        
        /// 一行个数
        var rowCount: Int = 3
        
        /// 间隔
        var itemSpace: CGFloat = 10
        
        /// 高度变化
        var heightBlock: ((CGFloat)->Void)?
        
        /// 按钮回调
        var btnPostBlock: (()->Void)?
        
        /// 删除区域
        weak var vDeleteArea: MomentsDeleteView?
        
        /// 数据
        var arrData: [UIImage] = [] {
            didSet {
                collectionView.reloadData()
            }
        }
        
        /// 初始化
        override init(frame: CGRect) {
            super.init(frame: frame)
            
            btnPost.snp.makeConstraints { (make) in
                make.left.top.equalTo(0)
                make.size.equalTo(CGSize.zero)
            }
            
            collectionView.snp.makeConstraints { (make) in
                make.left.top.right.bottom.equalToSuperview()
            }
        }
        
        /// 上传按钮点击回调
        @objc private func btnPostClick(_ sender: UIButton) {
            btnPostBlock?()
        } 
        
        /// cell个数
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            let count = arrData.count
            if (count > 0 && count < maxCount) {
                let lines = count / rowCount
                if (lines != numberOfLines) {
                    numberOfLines = lines
                }
            }
            return min(count + 1, maxCount)
        }
        
        /// cell样式
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MomentsViewCell", for: indexPath) as! MomentsViewCell
            cell.imageView.image = indexPath.row < arrData.count ? arrData[indexPath.row] : nil
            return cell
        }
        
        /// cell将要展示
        func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
            if indexPath.row == arrData.count && indexPath.row < maxCount {
                let pos = convert(cell.frame.origin, from: collectionView)
                btnPost.snp.updateConstraints { (make) in
                    make.top.equalTo(pos.y)
                    make.left.equalTo(pos.x)
                }
            }
            btnPost.isHidden = arrData.count + 1 > maxCount
        }
        
        /// cell宽高
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            if (itemLength == 0) {
                itemLength = (collectionView.frame.width - itemSpace * CGFloat(rowCount - 1)) / CGFloat(rowCount)
            }
            return CGSize(width: itemLength, height: itemLength)
        }
        
        /// 长按事件
        public func longPress(_ gesture: UILongPressGestureRecognizer) {
            guard let target = gesture.view, isUserInteractionEnabled else {
                return
            }
            switch gesture.state {
            case .began:
                beginInteractiveMovement(target, position: gesture.location(in: target))
            case .changed:
                updateInteractiveMovement(target, position: gesture.location(in: target))
            case .ended:
                endInteractiveMovement(target)
            case .cancelled:
                endInteractiveMovement(target)
            default:
                break
            }
        }
        
        /// 长按开始
        private func beginInteractiveMovement(_ target: UIView, position: CGPoint) {
            
            guard let indexPath = collectionView.indexPathForItem(at: target.convert(position, to: collectionView)), indexPath.row < arrData.count else {
                return
            }
            
            let cell: MomentsViewCell = collectionView.cellForItem(at: indexPath) as! MomentsViewCell
            cell.isHidden = true
            
            dragingItem.frame = CGRect(origin: collectionView.convert(cell.frame.origin, to: target), size: cell.frame.size)
            dragingItem.image = cell.imageView.image
            dragingItem.isHidden = false
            
            UIView.animate(withDuration: 0.1, animations: {
                self.dragingItem.center = position
                self.dragingItem.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
                self.vDeleteArea?.showView()
            }) { (finished) in
                self.indexPath = indexPath
            }
        }
        
        /// 长按过程
        private func updateInteractiveMovement(_ target: UIView, position: CGPoint) {
            
            guard let indexPath = indexPath else {
                return
            }
            
            dragingItem.center = position
            
            if let vDeleteArea = vDeleteArea {
                if vDeleteArea.frame.contains(position) {
                    canDelete = true
                    vDeleteArea.isDelete = true
                } else {
                    canDelete = false
                    vDeleteArea.isDelete = false
                }
            }
            
            guard let targetIndexPath = collectionView.indexPathForItem(at: target.convert(position, to: collectionView)), targetIndexPath.row < arrData.count else {
                return
            }
            
            /// 交换位置
            collectionView.moveItem(at: indexPath, to: targetIndexPath)
            
            let obj = arrData[indexPath.row]
            arrData.remove(at: indexPath.row)
            arrData.insert(obj, at: targetIndexPath.row)
            
            self.indexPath = targetIndexPath
        }
        
        /// 长按结束
        private func endInteractiveMovement(_ target: UIView) {
            
            guard let indexPath = indexPath, let cell = collectionView.cellForItem(at: indexPath) else {
                return
            }
            
            isUserInteractionEnabled = false
            
            if (canDelete) {
                UIView.animate(withDuration: 0.1, animations: {
                    self.vDeleteArea?.hideView()
                }, completion: { (finished) in
                    self.arrData.remove(at: indexPath.row)
                    self.collectionView.reloadData()
                    cell.isHidden = false
                    self.dragingItem.isHidden = true
                    self.indexPath = nil
                    self.vDeleteArea?.isDelete = false
                    self.isUserInteractionEnabled = true
                })
            } else {
                let center = target.convert(cell.center, from: collectionView)
                UIView.animate(withDuration: 0.25, animations: {
                    self.dragingItem.transform = .identity
                    self.dragingItem.center = center
                    self.vDeleteArea?.hideView()
                }, completion: { (finished) in
                    cell.isHidden = false
                    self.dragingItem.isHidden = true
                    self.indexPath = nil
                    self.vDeleteArea?.isDelete = false
                    self.isUserInteractionEnabled = true
                })
            }
        }
        
        /// 判断是不是按钮点击
        override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
            if !btnPost.isHidden && (collectionView.convert(btnPost.frame, from: self).contains(point)) {
                return btnPost
            }
            return super.hitTest(point, with: event)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    class MomentsViewCell: UICollectionViewCell {
        
        var imageView: UIImageView!
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            
            imageView = UIImageView()
            imageView.contentMode = .scaleAspectFill
            imageView.layer.masksToBounds = true
            addSubview(imageView)
            
            imageView.snp.makeConstraints { (make) in
                make.left.right.top.bottom.equalToSuperview()
            }
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    /// 上传按钮
    class MomentsPostButton: UIButton {
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            
            let borderWidth: CGFloat = 2
            let borderColor: UIColor = .gray
            
            backgroundColor = UIColor.groupTableViewBackground
            
            /// 横
            let vHorizontal = UIView()
            vHorizontal.backgroundColor = borderColor
            addSubview(vHorizontal)
            
            vHorizontal.snp.makeConstraints { (make) in
                make.center.equalToSuperview()
                make.width.equalToSuperview().multipliedBy(0.25)
                make.height.equalTo(borderWidth)
            }
            
            /// 竖
            let vVertical = UIView()
            vVertical.backgroundColor = borderColor
            addSubview(vVertical)
            
            vVertical.snp.makeConstraints { (make) in
                make.width.equalTo(borderWidth)
                make.center.equalToSuperview()
                make.height.equalToSuperview().multipliedBy(0.25)
            }
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    class MomentsDeleteView: UILabel {
        
        let normalText = "拖到此处删除"
        
        let normalColor = UIColor(hex: "ff0033").withAlphaComponent(0.9)
        
        let deleteText = "松手即可删除"
        
        let deleteColor = UIColor(hex: "cc0000").withAlphaComponent(0.9)
        
        var isDelete: Bool = false {
            didSet {
                if isDelete {
                    text = deleteText
                    backgroundColor = deleteColor
                } else {
                    text = normalText
                    backgroundColor = normalColor
                }
            }
        }
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            backgroundColor = normalColor
            text = normalText
            textColor = .white
            font = UIFont.systemFont(ofSize: 14)
            textAlignment = .center
        }
        
        func showView() {
            transform = .identity
        }
        
        func hideView() {
            transform = CGAffineTransform(translationX: 0, y: 60)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    

    相关文章

      网友评论

          本文标题:swift 类微信朋友圈九宫格拖拽图

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