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

时间:2013-04-05 18:27:24

标签: ios screen-brightness

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

7 个答案:

答案 0 :(得分: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
}()

答案 1 :(得分: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];
    }
}

答案 2 :(得分:1)

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

答案 3 :(得分:0)

根据Charlie Price的最佳答案,这里有一种方法可以将屏幕亮度的变化“动画化”为任何所需的值。

- (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];
        });
    }
}

答案 4 :(得分:0)

或者您可以使用 NSTimer 而不是while循环和performSelector。

finalValue - 是您想要实现的价值。

计时器每次闪耀30次,持续时间0.02秒(你可以选择不同但顺畅的东西)并改变亮度值。

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
}

答案 5 :(得分:0)

雨燕5

import Foundation

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

    }
}

答案 6 :(得分:0)

如果您需要更改特定ViewController的亮度,则可以使用此帮助程序

import Foundation
import UIKit

final class ScreenBrightness {

    private var timer: Timer?
    private var brightness: CGFloat?
    private var isBrighteningScreen = false
    private var isDarkeningScreen = false

    private init() { }

    static let shared = ScreenBrightnessHelper()

    //Увеличение яркости экрана до максимального уровня
    func brightenDisplay() {
        resetTimer()
        isBrighteningScreen = true
        if #available(iOS 10.0, *), timer == nil {
            brightness = UIScreen.main.brightness
            timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { (timer) in
                UIScreen.main.brightness = UIScreen.main.brightness + 0.01
                if UIScreen.main.brightness > 0.99 || !self.isBrighteningScreen {
                    self.resetTimer()
                }
            }
        }
        timer?.fire()
    }

    //Затемнение экрана до предыдущего уровня
    func darkenDisplay() {
        resetTimer()
        isDarkeningScreen = true
        guard let brightness = brightness else {
            return
        }
        if #available(iOS 10.0, *), timer == nil {
            timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { (timer) in
                UIScreen.main.brightness = UIScreen.main.brightness - 0.01

                if UIScreen.main.brightness <= brightness || !self.isDarkeningScreen {
                    self.resetTimer()
                    self.brightness = nil
                }
            }
            timer?.fire()
        }
    }

    private func resetTimer() {
        timer?.invalidate()
        timer = nil
        isBrighteningScreen = false
        isDarkeningScreen = false
    }
}

在viewWillAppear中调用ScreenBrightness.shared.brightenDisplay(),如果要对其进行更改,请调用方法ScreenBrightness.shared.darkenDisplay(),该方法将使亮度变回