美文网首页Swift
swift4.0 类似头条频道拖拽排序

swift4.0 类似头条频道拖拽排序

作者: 千年积木 | 来源:发表于2018-07-04 15:55 被阅读94次

    代码是完整的可以直接用

    import UIKit
    
    class TTDataSourceTool: NSObject {
    
        static var share = TTDataSourceTool.init()
        fileprivate override init() {}
        
        var selectedArr = ["推荐","河北","财经","娱乐","体育","社会","NBA","视频","汽车","图片","科技","军事","国际","数码","星座","电影","时尚","文化","游戏","教育","动漫","政务","纪录片","房产","佛学","股票","理财"]
        
        var unselectedArr = ["有声","家居","电竞","美容","电视剧","搏击","健康","摄影","生活","旅游","韩流","探索","综艺","美食","育儿"]
     
        var isEdit = false
        
        var snapShotCellView:UIView?
        var originalCell:TTChannelSortCell?
        var startPoint:CGPoint?
        var indexPath:IndexPath?
        var nextIndexPath:IndexPath?
    }
    
    extension TTDataSourceTool{
        
        
    }
    
    import UIKit
    
    class TTChannelSortCell: UICollectionViewCell {
        
        typealias CellGestureCallBack = (_ gesture:UIGestureRecognizer)->()
        
        var cellGCB:CellGestureCallBack?
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            contentView.addSubview(c_title)
            contentView.addSubview(c_image)
            
            self.addGestureRecognizer(self.longG)
            self.addGestureRecognizer(self.panG)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        var isEdit:Bool = false {
            didSet{
                c_image.isHidden = !isEdit
            }
        }
        
        var titles:String?{
            didSet{
                c_title.text = titles
            }
        }
        
        lazy var c_image:UIImageView = {
            let img = UIImageView.init(frame: CGRect.init(x: 0, y: 0, width: 20, height: 20));
            img.image = UIImage.init(named: "close");
            return img
        }()
        
        lazy var c_title:UILabel = {
            let lb = UILabel.init(frame: self.bounds)
            lb.textColor = UIColor.black
            lb.font = UIFont.systemFont(ofSize: 16)
            lb.layer.borderWidth = 1.0
            lb.layer.borderColor = UIColor.lightGray.cgColor
            lb.layer.cornerRadius = 5;
            lb.textAlignment = .center
            return lb
        }()
        
        
       fileprivate lazy var longG:UILongPressGestureRecognizer = {
            let lp = UILongPressGestureRecognizer.init(target: self, action: #selector(gestureAction(gesture:)))
            lp.delegate = self;
            return lp;
        }()
        
       fileprivate lazy var panG:UIPanGestureRecognizer = {
            let lp = UIPanGestureRecognizer.init(target: self, action: #selector(gestureAction(gesture:)))
            lp.delegate = self;
            return lp;
        }()
        
        
    }
    
    extension TTChannelSortCell:UIGestureRecognizerDelegate{
        
        override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
            
            return true
        }
        
    
        @objc func gestureAction(gesture:UIGestureRecognizer) {
            guard let _ = self.cellGCB else {return}
            self.cellGCB!(gesture)
        }
        
    }
    
    
    import UIKit
    
    private let SCREEN_WIDTH = UIScreen.main.bounds.width
    private let SCREEN_HEIGHT = UIScreen.main.bounds.height
    
    private let ChannelViewCellIdentifier = "ChannelViewCellIdentifier"
    private let ChannelViewHeaderIdentifier = "ChannelViewHeaderIdentifier"
    
    class TTChannelSortVC: UIViewController {
    
        var selArr = [String]()
        var unselArr = [String]()
        
        init(selected:[String],unselected:[String]) {
            super.init(nibName: nil, bundle: nil)
            selArr = selected
            unselArr = unselected
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            setUI()
        }
    
        func setUI(){
            self.view.addSubview(containView)
        }
        
        lazy var containView:UICollectionView = {
            let v = UICollectionView.init(frame: self.view.bounds, collectionViewLayout: TTContainFlowLayout.init())
            v.delegate = self;
            v.dataSource = self;
            v.backgroundColor = UIColor.white
            v.register(TTChannelSortCell.self, forCellWithReuseIdentifier: ChannelViewCellIdentifier)
            v.register(TTSectionHeadView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: ChannelViewHeaderIdentifier)
            return v;
        }()
    
        var isEdit = false
        
        lazy var dsTool:TTDataSourceTool = {
            let tool = TTDataSourceTool.share;
            return tool;
        }()
    }
    
    //MARK:数据源代理
    extension TTChannelSortVC:UICollectionViewDataSource{
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return section == 0 ? selArr.count : unselArr.count
        }
        
        func numberOfSections(in collectionView: UICollectionView) -> Int {
            return 2
        }
        
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            
            let cell:TTChannelSortCell = collectionView.dequeueReusableCell(withReuseIdentifier: ChannelViewCellIdentifier, for: indexPath) as! TTChannelSortCell
            cell.titles = indexPath.section == 0 ? selArr[indexPath.row] : unselArr[indexPath.row]
            cell.isEdit = isEdit;
            cell.cellGCB = { gesture in
                self.gestureAction(gesture: gesture)
            }
            return cell
        }
        
        func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
            
            let headView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: ChannelViewHeaderIdentifier, for: indexPath) as! TTSectionHeadView
            
            headView.titles = indexPath.section == 0 ? headView.titleArr[0] : headView.titleArr[1]
            headView.callBack = {
                self.isEdit = !self.isEdit
                collectionView.reloadData();
            }
            return headView;
        }
    }
    
    //MARK:手势方法
    extension TTChannelSortVC{
        
        ///手势触发
        func gestureAction(gesture:UIGestureRecognizer) {
            
            let cell = gesture.view as? TTChannelSortCell
            print("我点击的",cell?.titles ?? "")
            guard let _ = cell else {return}
            
            let indexPath = containView.indexPath(for: cell!)
            guard indexPath?.section == 0 else {return}
    
            if gesture.state ==  UIGestureRecognizerState.began{
               
                if gesture.isKind(of: UILongPressGestureRecognizer.self){
                    self.isEdit = true
                    //修改显示
                    let arr = containView.visibleCells
                    arr.forEach { (cell) in
                        let sc = cell as! TTChannelSortCell
                        sc.isEdit = self.isEdit
                    }
                }
                guard self.isEdit else{return}
                dsTool.snapShotCellView = cell?.snapshotView(afterScreenUpdates: true)
                dsTool.originalCell = cell;
                dsTool.originalCell?.isHidden = true;
                dsTool.snapShotCellView?.center = (cell?.center)!
                containView.addSubview(dsTool.snapShotCellView!)
                dsTool.startPoint = gesture.location(in: containView)
                dsTool.indexPath = containView.indexPath(for: cell!)
            }else if gesture.state ==  UIGestureRecognizerState.changed{
                guard let _ = dsTool.startPoint else{return}
                guard let _ = dsTool.snapShotCellView else{return}
                let tran_x = gesture.location(ofTouch: 0, in: containView).x - (dsTool.startPoint?.x)!
                let tran_y = gesture.location(ofTouch: 0, in: containView).y - (dsTool.startPoint?.y)!
                dsTool.snapShotCellView?.center = __CGPointApplyAffineTransform((dsTool.snapShotCellView?.center)!, CGAffineTransform.init(translationX: tran_x, y: tran_y));
                dsTool.startPoint = gesture.location(ofTouch: 0, in: containView);
                
                let arrCell = containView.visibleCells;
                for cell in arrCell {
                    //跳过自己
                    if containView.indexPath(for: cell) == dsTool.indexPath{
                        continue
                    }
                    //如果相交一半且两个视图Y的绝对值小于高度的一半就移动
                    let space = sqrt(pow((dsTool.snapShotCellView?.center.x)! - cell.center.x, 2) + pow((dsTool.snapShotCellView?.center.y)! - cell.center.y, 2))
                    if space <= (dsTool.snapShotCellView?.bounds.size.width)! * 0.5 && fabs((dsTool.snapShotCellView?.bounds.height)! - cell.bounds.height) <= (dsTool.snapShotCellView?.bounds.height)! * 0.5{
                        dsTool.nextIndexPath = containView.indexPath(for: cell)
                        if (dsTool.nextIndexPath?.item)! > (dsTool.indexPath?.item)!{
                            //更新数据源
                            let i = (dsTool.indexPath?.item)!
                            let ii = (dsTool.nextIndexPath?.item)!
                            for index in i ..< ii{
                                let temp = self.selArr[index]
                                self.selArr[index] = self.selArr[index + 1]
                                self.selArr[index + 1] = temp
                            }
                        }else{
                            //更新数据源
                            let ii = (dsTool.indexPath?.item)!
                            let i = (dsTool.nextIndexPath?.item)!
                            for index in 0 ..< ii - i{
                                guard index < ii else {return}
                                let temp = self.selArr[ii - index]
                                self.selArr[ii - index] = self.selArr[ii - index - 1]
                                self.selArr[ii - index - 1] = temp
                            }
                        }
                        containView.moveItem(at: dsTool.indexPath!, to: dsTool.nextIndexPath!)
                        dsTool.indexPath = dsTool.nextIndexPath
                        break
                    }
                }
                
                
            }else if gesture.state ==  UIGestureRecognizerState.ended{
                
                dsTool.snapShotCellView?.removeFromSuperview()
                dsTool.snapShotCellView = nil;
                dsTool.originalCell?.isHidden = false
            }
        }
    }
    
    
    //MARK:代理
    extension TTChannelSortVC:UICollectionViewDelegate{
        
        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            if indexPath.section == 1{
                let obj = unselArr[indexPath.row]
                selArr.append(obj)
                unselArr.remove(at: indexPath.row)
                collectionView.moveItem(at: indexPath, to: NSIndexPath.init(item: selArr.count - 1, section: 0) as IndexPath)
            }else if indexPath.section == 0{
                guard isEdit else{return}
                let obj = selArr[indexPath.row]
                unselArr.append(obj)
                selArr.remove(at: indexPath.row)
                collectionView.moveItem(at: indexPath, to: NSIndexPath.init(item: unselArr.count - 1, section: 1) as IndexPath)
            }
        }
    }
    
    //MARK:布局
    class TTContainFlowLayout: UICollectionViewFlowLayout {
        override func prepare() {
            headerReferenceSize = CGSize.init(width: SCREEN_WIDTH, height: 64.0)
            itemSize = CGSize.init(width:(SCREEN_WIDTH - 50) * 0.25 , height: 40)
            minimumLineSpacing = 10
            minimumInteritemSpacing = 10
            sectionInset = UIEdgeInsetsMake(10, 10, 10, 10)
        }
    }
    
    //MARK:分组头部
    class TTSectionHeadView: UICollectionReusableView {
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.backgroundColor = UIColor.lightGray
            addSubview(c_title)
            addSubview(bt)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        var callBack:(()->())?
        
        
        var isEdit:Bool = false {
            didSet{
                bt.isSelected = isEdit
            }
        }
        
        var titleArr = ["   我的频道","   推荐频道"]
        
        
        var titles:String?{
            didSet{
                c_title.text = titles
                if titles == "   推荐频道"{
                    bt.isHidden = true
                }else{
                    bt.isHidden = false
                }
            }
        }
        
        lazy var bt:UIButton = {
            let bt = UIButton.init(type: UIButtonType.custom)
            bt.frame = CGRect.init(x: SCREEN_WIDTH - 75, y: 17, width: 60, height: 30)
            bt.addTarget(self, action: #selector(btAction(bt:)), for: UIControlEvents.touchUpInside)
            bt.setTitle("编辑", for: UIControlState.normal)
            bt.setTitle("完成", for: UIControlState.selected)
            bt.layer.borderWidth = 1;
            bt.layer.borderColor = UIColor.white.cgColor;
            bt.layer.cornerRadius = 5;
            return bt
        }()
        
        
        @objc func btAction(bt:UIButton){
            if callBack != nil {
                callBack!()
            }
        }
        
        lazy var c_title:UILabel = {
            let lb = UILabel.init(frame: self.bounds)
            lb.textColor = UIColor.white
            lb.font = UIFont.systemFont(ofSize: 16)
            return lb
        }()
    }
    
    

    相关文章

      网友评论

        本文标题:swift4.0 类似头条频道拖拽排序

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