如何使用淡入淡出动画设置屏幕亮度?

lou*_*smr 8 ios screen-brightness

是否可以在iOS 5.1+上设置屏幕亮度变化的动画?我正在使用,[UIScreen mainScreen] setBrightness:(float)]但我认为突然的变化是丑陋的.

小智 11

斯威夫特 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)
            }
        }
        
    }
}
Run Code Online (Sandbox Code Playgroud)


kha*_*len 10

在尝试使用之前的动画进行动画制作另一个值时,我遇到了已接受答案的问题.此解决方案取消正在进行的动画和动画到新值:

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
}()
Run Code Online (Sandbox Code Playgroud)


Cha*_*ice 6

我不知道这是否可以通过其他方式"动画",但你可以自己动手.例如,以下示例代码连接到UI中的"Full Bright"和"Half Bright"按钮.它使用performSelector ... afterDelay每10ms将亮度改变1%,直到达到目标亮度.您可以根据一些实验选择合适的变化率.实际上,我认为刷新率为60赫兹,因此在小于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];
    }
}
Run Code Online (Sandbox Code Playgroud)