是否可以在iOS 5.1+上设置屏幕亮度变化的动画?我正在使用[UIScreen mainScreen] setBrightness:(float)]
,但我认为突然的变化是丑陋的。
答案 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(),该方法将使亮度变回