Does iOS send notifications when the system changes the screen brightness? - iphone

Problem is, my reading app has a button that puts it into dark theme mode. The brightness gets reduced by 10%. When the user returns to the normal mode, it is set back to the remembered brightness. But in the meantime the actual system brightness could have changed due to auto-brightness adjustment or even the user going to Settings and changing it there.
The problem with the brightness property is that you only query actual screen brightness and whatever you set is only temporarily until the user locks the screen. upon unlock the system reverts to system brightness.
If iOS would send notifications when the system changes the brightness that would be helpful. Couldn't find anything on this in the docs.

Search for UIScreenBrightnessDidChangeNotification which is part of the UIScreen class. It is available from iOS 5.0 and above.

If you want to set the brightness back to a programatic value when the device is unlocked again, observe the UIApplicationDidBecomeActiveNotification notification and set the brightness back to you desired level in your selector.
I've done some more research on this whole brightness thing and here's what I found:
The UIScreenBrightnessDidChangeNotification gets called ONLY when the system changes the brightness or when the user changes the brightness from the control panel or settings. NOT when you change the brightness programatically.
What I assumed from this Apple Doc here (see below) is that brightness will not change anymore after you set it programatically.
Brightness changes made by an app remain in effect until the device is
locked, regardless of whether the app is closed. The system brightness
(which the user can set in Settings or Control Center) is restored the
next time the display is turned on.
However I found this not to be true (or I'm misinterpreting it). The brightness does change (and UIScreenBrightnessDidChangeNotification does get called) after you set the brightness programatically. However it ONLY gets called when the system thinks it should increase or decrease the brightness (due to changes in the environment brightness) *. If the brightness of the environment stays the same your screen will stay as bright as you set it programatically.
What does this mean? Well, 2 things:
If you want to keep the brightness at the level you set it programatically, no matter environment changes, you have to observe the UIScreenBrightnessDidChangeNotification and reset the brightness to your desired level every time it's called.
If you want to go back to the "system" brightness, well you can't really, because you simply can't tell what the system brightness would be if environment changes took place (because you are resetting it every time). You have 2 options for this.
Remember the brightness before you set your brightness programatically and set it back to that value. Or
Put the brightness to 0.5 and let the system to it's job.
The 'danger' in both situations is that it will stay on the value you set it until an environment brightness change is detected.
*There are 2 special cases... when you set the brightness to 0.0 and the system thinks it should decrease brightness nothing happens because it's already on 0.0. Secondly, when you set it to 1.0 it will stay on 1.0, no matter how the environment changes.

Related

Getting notified when the screen brightness changes in macOS

I'm writing a macOS app in which I'd like to do something with the value of the screen brightness as soon as it changes.
I can determine what the screen brightness is by iterating over IOServices with IOServiceGetMatchingServices() then using IODisplayGetFloatParameter() to obtain the kIODisplayBrightnessKey parameter of the IODisplayConnect services I found, as explained in this answer, but I don't know how to find out when the brightness has changed.
Is there a way for my app to get notified as soon as the screen brightness has changed?
I could poll, and I know how to do that, but that's not what I'm looking for. I'm looking for something like UIScreen.brightnessDidChangeNotification, but for macOS.

CIColorControls wrong brightness

I am change brightness value of the image to negative value and trying to compare result image with apple photo editor.
Original
Edited by me
Edited by Apple Photo Editor
As you can see, my CIFilter change brightness of white part of the image too. Apple Editor changes brightness of person only.
My code is simple:
filter.setValue(NSNumber(value: -0.4), forKey: kCIInputBrightnessKey)
It makes no difference whether I increase the brightness or decrease it. The brightness of the entire image changes. Apple Editor changes only part of the image
The "Brightness" slider in Photos is not mapped to the "traditional" brightness value (that is used in CIColorControls). Apple uses more sophisticated algorithms under the hood that, among others, take the image's content into account. I'm afraid there's no single core image filter that can reproduce that result. But it looks like Photos also increased the contrast when reducing the brightness, so you could try that.

How to set initial position of Picture in Picture? (AVPictureInPictureController / AVPlayerViewController)

For default mode, when user starts Picture-In-Picture, the little windows starts at the latest position (latest pip window closed position).
Is there a way to set starting position like: top-left, top-right, bottom-left, bottom-right?
There is no way to set the starting position of an AVPictureInPictureController.
There isn't really a reason to set the location (it's going to be on top of other apps, not your own), and the user can change the location of it at anytime, out of your control.
From the AVPictureInPictureController documentation:
If an app invokes PiP in a way that is not under the immediate direction of the user, it will be rejected by the App Store.
Also, it is also not suggested to create a subclass of AVPictureInPictureController:
Do not subclass AVPictureInPictureController. Overriding this class’s methods is unsupported and results in undefined behavior.
Creating the functionality of this would require the use of private APIs anyways, and that's a guaranteed rejection by Apple.

Unable to restore brightness on application exit

I have a feature in my app (a metronome app for musicians) to dim the screen in order to save on battery life. To set the brightness, I am using:
[UIScreen mainScreen].brightness = 0.1;
I am saving the original brightness on app start up in viewDidLoad(...) and saving that to my User Defaults.
When changing views within the app, I retrieve the original brightness from User Defaults and restore with a call:
[UIScreen mainScreen].brightness = originalBrightness;
This works fine. I have NSLog(...) messages showing the original value, etc... so the mechanism works.
The issue I am having is how to restore the original brightness on application exit as the Home button is pressed.
I have added similar code to my application delegate methods for:
applicationWillResignActive(...)
applicationDidEnterBackground(...)
applicationWillTerminate(...)
They each have a method call to set the screen brightness as before in the view with similar NSLog(...)s showing the retrieved original brightness...and it is all correct. I have also debugged in and the calls to set brightness are being made...but the app exits, and the device screen is still at the lower, dimmed level.
Finally, if you click the "lock" button on top, then press the Home button to wake it up...the brightness is correct.
My suspicion is that whatever action or event is triggered with my call to set the brightness when the app is exiting is not getting through, maybe due to an invalid state or similar.
Also, my app is set to NOT run in the background, set in the info.plist as:
Application does not run in background YES
Any help would be appreciated.
Thanks!
iOS allows that app a little bit of time before exiting. You might try a sleep for a fraction of a second after setting the brightness.
If you read https://devforums.apple.com/thread/139813 carefully it says that brightness changes are not permanent. The original user brightness is back, when you hit the lock button and unlock it again. Actually, I had to restore my app brightness if user hits lock button while my app is running:
- (void)applicationDidBecomeActive:(UIApplication *)application{
[self setBrightness];
}
Not had much joy with this. Workaround was to reset brightness on a ViewController viewWillDisappear. Not a great solution but the only one I have found so far to work (this has been broken for years...)

Dim iPhone Screen, but don't let it sleep

Update
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIScreen_Class/index.html#//apple_ref/occ/instp/UIScreen/brightness
That's the Apple Doc for controlling screen brightness. Below is the original question.
I have found by using Google that I can disable the iPhone going to sleep in an application by using:
application.idleTimerDisabled = YES;
so the code looks like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
// This disables the autosleep I added this to TEST,
// delete later if you want:-
application.idleTimerDisabled = YES;
[window addSubview:switchViewController.view];
[window makeKeyAndVisible];
Perfect, it works well. However, my question is, can I somehow disable the iPhone from going to sleep, while still allowing the screen to dim? Or perhaps dim the screen myself in the app as to save battery power?
I definitely don't want the iPhone sleeping, but I'd also like to be user friendly/battery friendly and dim the screen. (You know, like how you can set the iPhone to dim the screen X seconds before it goes to sleep.) Is there an effective way to do this?
I'm pretty sure there's nothing in the official SDK.
[(id)[UIApplication sharedApplication] setBacklightLevel:0.3f]; // or whatever value
works, but is of course undocumented. The recent experience with UIGetScreenImage indicates that perhaps the right strategy with useful but undocumented APIs is to use them and see what happens.
Failing that, has anybody ever measured if the phone's power consumption goes down if it's showing a black image, or does it not help unless you can turn down the backlight?
I use a "nightstand" type alarm clock app that, if you double-tap its clock screen, dims the screen by some amount.
I believe what it's probably really doing is laying a partially-opaque black UIView over its entire content. I think the backlight isn't really dimmed, but the black color laid over the screen makes it seem dimmer. It works.
Can you set proximityState to trick the iPhone into thinking that it is close to someone's ear? This would work with the iPhone, but not the iPod touch. There is no way to selectively turn adjust the brightness ... apps that dim the screen typically do so by putting a partly transparent image over the current one.
Starting with iOS 5 you can set UIScreen's brightness:
This property is only supported on the main screen. The value of this
property should be a number between 0.0 and 1.0, inclusive.
Brightness changes made by an app remain in effect only while the app
is active. The system restores the user-supplied brightness setting at
appropriate times when your app is not in the foreground. So if you
change the value of this property, you do not need to record the
previous value and restore it when your app moves to the background.
You can use this approach http://oleb.net/blog/2014/02/alarm-clock-apps-ios/
Just add a parameter into info.plist. And your app still run when your screen dim, your device locked.
When you debug, your app still run and never dim automatically, you just press lock button to test.
When you run your app without debug, you can see this feature do, like Music app of Apple, the music still play when device go to turn off screen.