2016-11-28 6 views
1

CALayer配列の最後の要素の背景色を変更しようとしています。ここに私のViewクラス全体がありますが、CALayerの最後の要素に実際にアクセスしようとするのはわずか2-3行です。ここでSwift:CALAYの変更CALayerの背景色が配列

は私progressViewClassであり、私は私の問題がどこにあるかを正確にコメントを入れて:

class ProgressBarView: UIView { 

//Variables for progress bar 
var holdGesture = UILongPressGestureRecognizer() 
let animation = CABasicAnimation(keyPath: "bounds.size.width") 
var layerHolder = [CALayer]() 
var widthIndex = CGPoint(x: 0, y: 0) 
var nextXOffset = CGFloat(0.0) 
var checkIfFull = CGFloat() 
var newLayer : CALayer? 
var progressBarAnimationDuration : CFTimeInterval = (MainController.sharedInstance.totalMiliSeconsToRecord/10) 

// Only override draw() if you perform custom drawing. 
// An empty implementation adversely affects performance during animation. 
override func draw(_ rect: CGRect) { 

} 

func startProgressBar(){ 

    if(RecordingViewController().currentCameraMode == .recordingMode || RecordingViewController().currentCameraMode == .record1stClipMode) { 

     newLayer = CALayer() 
     newLayer?.frame = CGRect(x: nextXOffset, y: 0, width: 0, height: self.bounds.height) 
     newLayer?.backgroundColor = UIColor(red:0.82, green:0.01, blue:0.11, alpha:1.0).cgColor 

     //print("before \(nextXOffset)") 
     newLayer?.anchorPoint = widthIndex 
     animation.fromValue = 0 
     animation.toValue = self.bounds.width - nextXOffset 
     animation.duration = progressBarAnimationDuration - ((MainController.sharedInstance.miliSecondsPassed)/10) 
     self.layer.addSublayer(newLayer!) 

     //print("Long Press Began") 
     newLayer?.add(animation, forKey: "bounds.size.width") 

    } 
    else{ 
     stopProgressBar() 
    } 
} 

func stopProgressBar(){ 
    if(RecordingViewController().currentCameraMode != .recordingMode){ 

      pauseLayer(layer: newLayer!) 

      newLayer?.frame = (newLayer?.presentation()!.frame)! 
      nextXOffset = (newLayer?.frame.maxX)! 
      layerHolder.append(newLayer!) 
      print("Layerholder has elements : \(layerHolder.count)") 
    } 
} 

// HERE IS MY PROBLEM 
func highlightLastLayer(){ 
    print("in highlight last layer Layerholder has elements : \(layerHolder.count)") 

    // I CAN HIDE THE CALAYER SO I BELIEVE IM ACCESSING THE CORRECT LAYER 
    // layerHolder.last?.isHidden = true 

    // This is suppose to change the last element background color to blue but doesnt 
    layerHolder.last?.backgroundColor = UIColor.blue.cgColor 
} 

// ALSO MY PROBLEM 
func unhighlightLastLayer(){ 
    print("inside unhighlight last layer") 

    // I CAN HIDE THE CALAYER SO I BELIEVE IM ACCESSING THE CORRECT LAYER 
    //layerHolder.last?.isHidden = false 

    // Changes CALayer back to red 
    layerHolder.last?.backgroundColor = UIColor(red:0.82, green:0.01, blue:0.11, alpha:1.0).cgColor 
} 

//Function to pause the Progress Bar 
func pauseLayer(layer : CALayer){ 
    let pausedTime : CFTimeInterval = layer.convertTime(CACurrentMediaTime(), from: nil) 
    layer.speed = 0.0 
    layer.timeOffset = pausedTime 

} 



} 

単に私がのViewControllerにprogressViewオブジェクトを作成し、特定のボタン入力に基づいて、これらの関数を呼び出す、置きます。このビューは、本質的に、多くのビデオ録画アプリケーションで録画した量を示すプログレスバーです。 highlightLastLayerでは、 "layerHolder"配列の最後の要素をつかみ、その色を青に変更しようとしています。単純な権利ですか?動作しません。何か案は?

+1

「highlightLastLayer'と 'unhighlightLastLayer'はいつ呼びますか?あなたは本当にメインスレッドでそれをやっていますか?あなたがカスタム描画をしていない場合、 'drawRect'をオーバーライドしないように注意してください。 Appleは、ビュークラスを作成するときにコメントで警告することさえできます。 –

+0

@MihaiFratu私は1000%ですhighlightLastLayerとunhighlightLastLayerを呼び出すのは、関数内に入れたプリントメッセージのためです。私はdrawRectをオーバーライドする何も書かなかったので、それはうまくいくはずです。あなたが見ることができる何かが、なぜこれがうまくいかないかを説明していますか?上のコードをすべて別のファイルにコピーし、ビューコントローラーでインスタンス化して、意味を確認することもできます。 – OriginalAlchemist

+0

上記のコードでは、2つのメソッドを呼び出す場所がありません。私はあなたが 'print'メッセージを見ていることを理解していますが、間違った時間に間違ったスレッドでやっているかもしれません。 'drawRect'について:それに何も書き込まないことは、パフォーマンスが賢明で、実際に何かをやっています。私はそれがあなたの問題と関係があると言っているわけではありません。私はちょうどあなたにアドバイスをしています:あなたがカスタム図面を作ろうとしないなら空のオーバーライドを削除してください。 –

答えて

0

ここでは、ハイライトとハイライトを呼び出しています。私はあなたが何かをlayerHolder配列に追加する唯一の時間だから "停止"または "一時停止"しているときにこれをやっていると確信しています。 「リアル」レイヤの代わりにプレゼンテーションレイヤーをアニメートするときに表示されるため、アニメーション化していないときにのみこれを行うことができます。速度をゼロに設定する代わりに、現在のアニメーション状態とコールレイヤのようにレイヤを設定します。 removeAllAnimationsを使用してプレゼンテーションレイヤーを消去し、代わりに実際のレイヤーを表示します。これで、すべての変更を行い、実際に表示されます。

+0

ええええと私は参照してください。したがって、現在のアニメーションの状態に見えるようにレイヤーを設定することで、何を意味するのかを明確にすることができます。私はlayer.removeAllAnimationsを呼び出すように設定しました。また、代わりに私のビューの実際のレイヤーを表示する方法は? 'newLayer?.frame =(newLayer?.presentation()!. frame)!'を取り除くと、レイヤーが画面に残りません。それは消える。 – OriginalAlchemist

+0

ニース!あなたは正しかった。私は速度を0に設定していましたが、アニメーションはまだ「進行中」でしたので、プロパティが変更されませんでした。アニメーションを削除すると、完全に機能しました! – OriginalAlchemist