IOS中手勢UIGestureRecognizer

流火行者發表於2015-03-19

通常在對檢視進行縮放移動等操作的時候我們可以用UIScrollView,因為它裡邊自帶了這些功能,我們要做的就是告訴UIScrollView的幾個相關引數就可以了

但是沒有實現旋轉的手勢即UIRotationGestureRecognizer 

IOS中手勢有很多:

UIRotationGestureRecognizer旋轉

UITapGestureRecognizer手指點選

UIPinchGestureRecognizer縮放

UISwipeGestureRecognizer手指快速掃過

UIPanGestureRecognizer手指拖拽移動

UILongPressGestureRecognizer長按

怎麼去實現自己的UIScrollView呢,還可以旋轉其Content呢?

需要UIRotationGestureRecognizer、UIPinchGestureRecognizer、UIPanGestureRecognizer的組合操作,先實現單個的操作

UIPanGestureRecognizer:

    func panOnView(panGesture:UIPanGestureRecognizer){
        
        println("PanClick!")
        switch(panGesture.state){
        case .Ended:
            println("end")
        case .Began:
//
            println("began")
//            velocity = CGPoint(x: panGesture.velocityInView(view).x * fps, y: panGesture.velocityInView(view).y * fps)//初始速度
        case .Changed:
            var trans = panGesture.translationInView(view)
            
            imageCenter!.transform = CGAffineTransformTranslate(imageCenter!.transform, trans.x / currentScale, trans.y / currentScale)
            panGesture.setTranslation(CGPointZero, inView: view)//translate的時候,center和position都不變
        default:
            println("default")
        }
//          adjustAnchorPointForGestureRecognizer(panGesture)
    }

UIPinchGestureRecognizer: 

    //縮放
    func pintchOnView(pintchGesture:UIPinchGestureRecognizer){
        
        currentScale = getViewScale(pintchGesture)
        switch pintchGesture.state{
        case .Began:
        case .Ended:
            println("end")
        case .Changed:
            var scale = pintchGesture.scale
            pintchGesture.view!.transform = CGAffineTransformScale(pintchGesture.view!.transform,scale, scale)
            pintchGesture.scale = 1
        default:
            println("default")
        }
        
    }

 UIPanGestureRecognizer:

    func rotateOnView(rotateGesture:UIRotationGestureRecognizer){
        switch rotateGesture.state{
        case .Began:
        case .Ended:
            println("end")
        case .Changed:
            imageCenter?.transform = CGAffineTransformRotate(imageCenter!.transform, rotateGesture.rotation)
            rotateGesture.rotation = 0
            println("changed")
        default:
            println("default")
        }
    }

 組合操作:

    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }

 一定要實現上面的函式才能組合操作,值得注意的是,因為縮放和旋轉都有個中心點的問題,也是常說的瞄點,瞄點不一樣,縮放和旋轉產生的效果完全不一樣

在檢視的Layer中有一個屬性anchorPoint這個點一般的預設值是(0.5,0.5)值大小是從0~1變化。如何理解瞄點,其實很簡單,比如說瞄點是P點,在P處的檢視上有一個很小的小花兒(假設有這個參照物),旋轉之後無論圖形變成什麼樣子,那個參照物小花兒還是在螢幕的原來的位置。比如P(0.5,0.5)那就是在檢視的正中心縮放旋轉,(0,0)就是左上角旋轉縮放,(1,1)就是右下角縮放旋轉。

如果在組合操作的時候不設定瞄點,每次手指操作的位置不同,瞄店都會變化,你不重現設定,很有可能你一旋轉,檢視都不知道跑哪裡去了,所以在所有手勢的Begin列舉的時候,應該手動再設定當前手指操作的點作為瞄點

    func adjustAnchorPointForGestureRecognizer(gestureRecognizer:UIGestureRecognizer){
        stopTimer()
        var piece = gestureRecognizer.view
        var locationInView = gestureRecognizer.locationInView(piece)
        var locationInSuperview = gestureRecognizer.locationInView(piece?.superview)
        piece?.layer.anchorPoint = CGPoint(x: locationInView.x / piece!.bounds.size.width, y: locationInView.y / piece!.bounds.size.height)
        piece?.center = locationInSuperview
        var trans = imageCenter!.transform
        imageCenter!.transform = CGAffineTransformTranslate(trans, -trans.tx / currentScale, -trans.ty / currentScale)
        panGestureRecognizer.setTranslation(CGPointZero, inView: view)
    }

 慣性:

在很多操作中我們都會看見檢視緩動的動畫效果,感覺好像檢視在受到阻力。很多動畫庫裡邊都有這樣的效果。但是動畫一般都是密封的過程,也就是說假如一個移動動畫持續5秒,那麼在這五秒結束之前,你不能對其座標手動賦值,除非你用一個全新的移動動畫來代替它。所以常用計時器來自己寫一個緩動的動畫

 var fps:CGFloat = 1 / 60.0//假設在每次fps時間間隔就對物件位置賦值

 var factor:CGFloat = 0.95//摩擦係數

 var velocity = ?//手指脫離螢幕的瞬間,檢視朝某個方向運動的速度,例如移動動畫的緩動,將手指抬起的座標減去抬起之前的上一個座標,這個距離向量作為初識的速度

定義一個計時器,時間間隔為fps,每隔fps,將velocity累乘一個factor係數。檢視的座標每次就加上velocity,直到velocity=0,終止計時器。不光移動動畫可以,任意的動畫都可以採用這個方法,簡單的實現緩動效果,好處在於,這種動畫緩動摩擦係數可以自己控制,而且可以在任意緩動的過程中對物件重新定位動畫的屬性,只要在之前關閉計時器即可

 

 

 

 

 

 

 

 

相關文章