3

以下のコードではCALayer、ユーザーが画面を押し続けているときに、画面の左側から画面の右側にアニメーション化しようとしています (longPressGestureRecognizer)。ユーザーが指を離すと、CALayer一時停止します。

var l = CALayer()
var holdGesture = UILongPressGestureRecognizer()
let animation = CABasicAnimation(keyPath: "bounds.size.width")

override func viewDidLoad() {
    super.viewDidLoad()
    setUpView()
}

func setUpView(){
    l.frame = CGRect(x: 0, y: 0, width: 0, height: 10)
    l.backgroundColor = UIColor.redColor().CGColor

    self.view.addGestureRecognizer(holdGesture)
    holdGesture.addTarget(self, action:"handleLongPress:")
}

func handleLongPress(sender : UILongPressGestureRecognizer){

    if(sender.state == .Began) { //User is holding down on screen
        print("Long Press Began")
        animation.fromValue = 0
        animation.toValue = self.view.bounds.maxX * 2
        animation.duration = 30
        self.view.layer.addSublayer(l)
        l.addAnimation(animation, forKey: "bounds.size.width")
    }
    else { //User lifted Finger
        print("Long press ended")
        print("l width: \(l.bounds.size.width)")
        pauseLayer(l)
    }
}

func pauseLayer(layer : CALayer){
    var pausedTime : CFTimeInterval = layer.convertTime(CACurrentMediaTime(), fromLayer: nil)
    layer.speed = 0.0
    layer.timeOffset = pausedTime
}

2 つの問題があります。

  1. アニメーションの後 (ユーザーが指を離したとき) の幅を印刷するとCALayer、常に 0 になります。幅をアニメーション化し、拡大するため、新しい幅が得られない理由がわかりませんCALayer

  2. ユーザーが指を離してからもう一度押したままにすると、 がCALayer消えます。画面に残して別のを作成する必要があります。CALayer削除しないので、なぜ消えてしまうのかわかりません。オブジェクトがまだ存在するメモリを確認しました。

問題#2への更新:別のレイヤーを作成するとCALayer思いますが、レイヤーを再度追加することはできません。コピーを作成するかUIView、レイヤーを追加できる を作成する必要があります。なぜそれが消えているのか、私はまだ理解していません。

4

1 に答える 1

7

基本的に、ユーザーが押しているときにレイヤーのサイズを変更しようとしています。特定のレイヤーのサイズを変更するために使用できる関数を次に示します。

原点を左にペグする場合は、最初にレイヤーのアンカーを設定する必要があります。

layer.anchorPoint = CGPointMake(0.0, 1);

func resizeLayer(layer:CALayer, newSize: CGSize) {

    let oldBounds = layer.bounds;
    var newBounds = oldBounds;
    newBounds.size = size;


    //Ensure at the end of animation, you have proper bounds
    layer.bounds = newBounds

    let boundsAnimation = CABasicAnimation(keyPath: "bounds")
    positionAnimation.fromValue = NSValue(CGRect: oldBounds)
    positionAnimation.toValue = NSValue(CGRect: newBounds)
    positionAnimation.duration = 30
} 

あなたの場合、一時停止したレイヤーをどこで再開しているのかわかりません。また、ユーザーがタップするたびに、handleLongPress メソッドに新しいアニメーションが追加されることにも注目してください。これは望ましくない効果をもたらします。理想的には、アニメーションを最初にのみ開始する必要があり、後で、以前に開始した一時停止したアニメーションを再開するだけです。

//Flag that holds if the animation already started..
var animationStarted = false

func handleLongPress(sender : UILongPressGestureRecognizer){

  //User is holding down on screen
  if(sender.state == .Began){

    if(animationStarted == false){
      let targetBounds =  CalculateTargetBounds() //Implement this to your need
      resizeLayer(layer, targetBounds)
      animationStarted = true
    }else {
      resumeLayer(layer)
    }
  }else {
    pauseLayer(layer)
  }
}
于 2016-01-11T05:25:16.330 に答える