2013-04-05 3 views

risposta

6

Non so se questo è "animabile" in qualche altro modo, ma potresti farlo tu stesso. Ad esempio il seguente codice di esempio è stato collegato ai pulsanti "Full Bright" e "Half Bright" nell'interfaccia utente. Usa performSelector ... afterDelay per modificare la luminosità dell'1% ogni 10ms fino a raggiungere la luminosità target. Sceglieresti un tasso di cambio appropriato in base ad alcuni esperimenti. In realtà, la frequenza di aggiornamento è, credo, 60 Hz, quindi probabilmente non c'è motivo di fare un cambiamento in un intervallo inferiore a 1/60 di secondo (la mia frequenza di esempio è stata scelta per avere una buona matematica). Sebbene si desideri eseguire questa operazione su un thread non dell'interfaccia utente, non blocca l'interfaccia utente.

- (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

Basato sul grande risposta di Charlie Price, ecco un metodo per "animare" un cambiamento di luminosità dello schermo a qualsiasi valore desiderato.

- (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

Ho riscontrato problemi con la risposta accettata quando si tenta di animare su un altro valore con un'animazione precedente in corso. Questa soluzione annulla un'animazione in corso e anima per il nuovo valore:

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

oppure è possibile utilizzare NSTimer invece di cicli while e performSelector.

finalValue - è il valore che si desidera raggiungere.

Il timer scatta 30 volte con una durata di 0,02 secondi per ciascuna (è possibile scegliere qualcosa di diverso ma uniformemente) e modifica il valore della luminosità.

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

Un'estensione Swift:

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) 
     } 
    } 
}