iOS技术博客·Blog自己尝试等装一下牛叉的demo

一种卡片翻转效果

2017-01-08  本文已影响545人  Hayder

最近业余写项目,实现了一种翻转卡片的效果,感觉效果还不错,记录下。首先来看下效果图:


卡片翻转效果图.gif

实现思路:
整个效果由一个背景图和3个卡片视图组成。获得一个数据数组后,在第一个卡片图上添加拖动Pan手势,修改卡片视图的transform中的Rotation属性。拖动结束后,刷新下3个卡片视图,每拖动结束一次就刷新一下3张卡片视图。

下面来看代码:
第一步: 初始化UI

//3张卡片视图
fileprivate var firstCell: WYClassBreakCell?
fileprivate var secondCell: WYClassBreakCell?
fileprivate var thirdCell: WYClassBreakCell?

fileprivate func setupUI(){
    
    //1.添加背景
    addSubview(bgImageView)
    
    //2.添加numLabel
    addSubview(numLable)
    
    //3.添加cell
    let margin: CGFloat = 10
    let cellWith: CGFloat = kScreenW - 2*30
    let cellHeight: CGFloat = cellWith/3*4
    let x: CGFloat = (kScreenW - cellWith)/2
    let y: CGFloat = (self.bounds.height - cellHeight)/2-30 - margin

    var lastView: UIView = self
    
    for i in 0..<3
    {
        let cell = WYClassBreakCell.classBreakCell()
        cell.layer.anchorPoint = CGPoint(x: 0.5, y: 2.0)
        cell.layer.position = CGPoint(x:0, y: 0)
        cell.frame = CGRect(x: x, y: y - CGFloat(i)*margin, width: cellWith, height: cellHeight)
        cell.tag = i + 1
        
        if(i != 0)
        {
            insertSubview(cell, belowSubview: lastView)
            lastView = cell
        }else
        {
            //只有第一张添加手势
            let pan = UIPanGestureRecognizer(target: self, action: #selector(pan(pan:)))
            cell.addGestureRecognizer(pan)
        
            addSubview(cell)
            lastView = cell
        }
        
    }
    
    //保存下属性
    firstCell = viewWithTag(1) as? WYClassBreakCell
    secondCell = viewWithTag(2) as? WYClassBreakCell
    thirdCell = viewWithTag(3) as? WYClassBreakCell
}

2.刷新卡片视图的方法
方法作用: 根据index下标设置模型数组中对应的数据,如果当前展示的卡片是第1张,他的模型数据在数组中的index = 0,参数就传0

fileprivate func refershUIWithIndex(index : Int)
{
    guard let classBraekList = classBraekList else{
        
        return
    }
    
    //设置页码
    numLable.numb.text = "\(index+1)"
    
    if index <= (classBraekList.count) - 3 //不是倒数三张
    {
        //1.初始化图形位置
        indentityTransFrom()
        
        //3.显示数据
        firstCell?.classBreakModel = (classBraekList[index])
        secondCell?.classBreakModel = (classBraekList[index+1])
        thirdCell?.classBreakModel = (classBraekList[index+2])

    }else{//倒数3张
        
        if index == (classBraekList.count) - 2 //还有2张
        {
            //初始化
            indentityTransFrom()
            
            //隐藏第3个Cell
            thirdCell?.isHidden = true
            
            //设置值
            firstCell?.classBreakModel = (classBraekList[index])
            secondCell?.classBreakModel = (classBraekList[index+1])
            
        }else if index == (classBraekList.count) - 1 //最后一张
        {
            //初始化
            indentityTransFrom()
            
            //隐藏第2,3个Cell
            thirdCell?.isHidden = true
            secondCell?.isHidden = true
            
            firstCell?.classBreakModel = (classBraekList[index])
        }
        
    }
//初始化图片位置
private func indentityTransFrom(){
    
    firstCell?.isHidden = false
    secondCell?.isHidden = false
    thirdCell?.isHidden = false
    
    if isFirst { //是否是第一张图片
        
        firstCell?.transform = CGAffineTransform.identity
        isFirst = false
    }else
    {
        firstCell?.transform = CGAffineTransform(rotationAngle: CGFloat(-M_PI_4) * 0.1)
        
        UIView.animate(withDuration: 0.2){
            
            self.firstCell?.transform = CGAffineTransform.identity
        }
        secondCell?.transform = CGAffineTransform.identity
        thirdCell?.transform = CGAffineTransform.identity
    }
}

3.手势处理
手势处理中有两个部分需要进行处理

 @objc fileprivate func pan(pan: UIPanGestureRecognizer)
  {
    //第二个视图
    let secondView = secondCell
    
    //判断手指是否抬起了,或者手势被取消了
    if pan.state == .ended || pan.state == .cancelled {
        
        if CGFloat((pan.view?.transform.b)!) < -0.25 //滑动比例超过0.25
        {
            UIView.animate(withDuration: 0.1, animations: {
                
                pan.view?.transform = CGAffineTransform(rotationAngle: CGFloat(-M_PI_2))
                
            }, completion: { (isFinished) in
                
                //刷新界面
                self.index += 1
                
                if self.index <= (self.classBraekList?.count)! - 1
                {
                    self.refershUIWithIndex(index: self.index)
                    
                }else //最后一张再滑动  从父视图上面移除
                {
                    self.removeFromSuperview()
                }

            })
            
        }else
        {
            pan.view?.transform = CGAffineTransform.identity
            secondView?.transform = CGAffineTransform.identity
        }
        
        if pan.translation(in: pan.view).x > 0 //右划
        {
            if index == 0
            {
                firstCell?.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI_4) * 0.1)
                
                UIView.animate(withDuration: 0.2){
                    
                    self.firstCell?.transform = CGAffineTransform.identity
                }
            }else
            {
                //更新下成员变量index的值
                index = index - 1
                
                //先设置first的transform 是 90度
                self.firstCell?.transform = CGAffineTransform(rotationAngle: CGFloat(-M_PI_2))
                
                UIView.animate(withDuration: 0.5){
                    
                    self.firstCell?.transform = CGAffineTransform.identity
                    
                    self.refershUIWithIndex(index: self.index)
                }
            }
        }
    }else  //手指正在滑动的时候
    {
        //获取手指的x偏移值
        let offsetX = pan.translation(in: pan.view).x
        
        if offsetX < 0
        {
            //计算百分比
            let percent: CGFloat = offsetX / self.bounds.width
            
            //计算这次要旋转的度数
            let radians = CGFloat(M_PI_4) * percent
            
            pan.view?.transform = CGAffineTransform(rotationAngle: radians)
            secondView?.transform = CGAffineTransform(rotationAngle: radians/2)
        }
    }
    }

这个效果的主要核心代码就是这些。

最后

项目的Demo地址:https://github.com/WzhGoSky/CardDance
如果你感觉这个效果不错,请给个❤️,码字也辛苦,😁😁

上一篇 下一篇

猜你喜欢

热点阅读