2013-04-05 25 views

答えて

6

これが他の方法で「アニメーション化可能」であるかどうかわかりませんが、あなた自身で行うことはできます。 たとえば、次のサンプルコードは、UIの「フルブライト」ボタンと「ハーフブライト」ボタンにフックされています。 performSelector ... afterDelayを使用して、目標輝度に達するまで輝度を10msごとに1%ずつ変更します。いくつかの実験に基づいて適切な変化率を選択します。実際にはリフレッシュレートは60Hzだから、1/60秒よりも小さい間隔で変更を行うことには何の意味もないでしょう(私の例のレートは素晴らしい計算をするために選ばれました)。これは非UIスレッドで行うこともできますが、UIをブロックすることはありません。チャーリー価格の偉大な答えに基づいて

- (IBAction)fullBright:(id)sender { 
    CGFloat brightness = [UIScreen mainScreen].brightness; 
    if (brightness < 1) { 
     [UIScreen mainScreen].brightness += 0.01; 
     [self performSelector:@selector(fullBright:) withObject:nil afterDelay:.01]; 
    } 
} 

- (IBAction)halfBright:(id)sender { 
    CGFloat brightness = [UIScreen mainScreen].brightness; 
    if (brightness > 0.5) { 
     [UIScreen mainScreen].brightness -= 0.01; 
     [self performSelector:@selector(halfBright:) withObject:nil afterDelay:.01]; 
    } 
} 
0

、ここでは、任意の所望の値に画面の明るさの変化を「アニメーション」のための方法があります。

- (void)graduallyAdjustBrightnessToValue:(CGFloat)endValue 
{ 
    CGFloat startValue = [[UIScreen mainScreen] brightness]; 

    CGFloat fadeInterval = 0.01; 
    double delayInSeconds = 0.01; 
    if (endValue < startValue) 
     fadeInterval = -fadeInterval; 

    CGFloat brightness = startValue; 
    while (fabsf(brightness-endValue)>0) { 

     brightness += fadeInterval; 

     if (fabsf(brightness-endValue) < fabsf(fadeInterval)) 
      brightness = endValue; 

     dispatch_time_t dispatchTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); 
     dispatch_after(dispatchTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [[UIScreen mainScreen] setBrightness:brightness]; 
     }); 
    } 
} 
7

以前のアニメーションが進行中の別の値にアニメートしようとすると、受け入れられた答えで問題が発生しました。このソリューションは、進行中のアニメーションをキャンセルし、新しい値にアニメーション化:

extension UIScreen { 

    func setBrightness(_ value: CGFloat, animated: Bool) { 
     if animated { 
      _brightnessQueue.cancelAllOperations() 
      let step: CGFloat = 0.04 * ((value > brightness) ? 1 : -1) 
      _brightnessQueue.add(operations: stride(from: brightness, through: value, by: step).map({ [weak self] value -> Operation in 
       let blockOperation = BlockOperation() 
       unowned let _unownedOperation = blockOperation 
       blockOperation.addExecutionBlock({ 
        if !_unownedOperation.isCancelled { 
         Thread.sleep(forTimeInterval: 1/60.0) 
         self?.brightness = value 
        } 
       }) 
       return blockOperation 
      })) 
     } else { 
      brightness = value 
     } 
    } 

} 

private let _brightnessQueue: OperationQueue = { 
    let queue = OperationQueue() 
    queue.maxConcurrentOperationCount = 1 
    return queue 
}() 
0

それとも、NSTimerの代わりに、whileループとperformSelectorを使用することができます。

finalValue - 達成したい値です。

タイマーは、それぞれ0.02秒で30回(違うがスムーズに選択できます)、輝度値を変更します。

weak var timer: NSTimer? 
var count = 1 
let maxCount = 30 
let interval = 0.02 


timer = NSTimer 
      .scheduledTimerWithTimeInterval(interval, 
              target: self, 
              selector: #selector(changeBrightness), 
              userInfo: nil, 
              repeats: true) 
func changeBrightness() 
{ 
    guard count < maxCount else { return } 

    let currentValue = UIScreen.mainScreen().brightness 
    let restCount = maxCount - count 
    let diff = (finalValue - currentValue)/CGFloat(restCount) 
    let newValue = currentValue + diff 
    UIScreen.mainScreen().brightness = newValue 

    count += 1 
} 
0

スウィフト拡張子:

extension UIScreen { 

    private static let step: CGFloat = 0.1 

    static func animateBrightness(to value: CGFloat) { 
     guard fabs(UIScreen.main.brightness - value) > step else { return } 

     let delta = UIScreen.main.brightness > value ? -step : step 

     DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { 
      UIScreen.main.brightness += delta 
      animateBrightness(to: value) 
     } 
    } 
} 
関連する問題