Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set screen brightness with fade animations?

Is it possible to animate the screen brightness change on iOS 5.1+? I am using [UIScreen mainScreen] setBrightness:(float)] but I think that the abrupt change is ugly.

like image 685
louissmr Avatar asked Apr 05 '13 18:04

louissmr


2 Answers

I ran into issues with the accepted answer when attempting to animate to another value with a previous animation in progress. This solution cancels an in-progress animation and animates to the new value:

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
}()
like image 169
khaullen Avatar answered Sep 16 '22 19:09

khaullen


Swift 5

import UIKit

extension UIScreen {
    
    public func setBrightness(to value: CGFloat, duration: TimeInterval = 0.3, ticksPerSecond: Double = 120) {
        let startingBrightness = UIScreen.main.brightness
        let delta = value - startingBrightness
        let totalTicks = Int(ticksPerSecond * duration)
        let changePerTick = delta / CGFloat(totalTicks)
        let delayBetweenTicks = 1 / ticksPerSecond
        
        let time = DispatchTime.now()
        
        for i in 1...totalTicks {
            DispatchQueue.main.asyncAfter(deadline: time + delayBetweenTicks * Double(i)) {
                UIScreen.main.brightness = max(min(startingBrightness + (changePerTick * CGFloat(i)),1),0)
            }
        }
        
    }
}
like image 24
Willian Avatar answered Sep 19 '22 19:09

Willian