I've started to use the new iOS 5 brightness setter in UIScreen. Is there a getter property I can use to know what the display brightness is set to on launch?
Thanks very much.
The same property. These are the methods I use to store the current brightness before changing it, then reset brightness to the previous value later:
- (void)dimScreen {
previousBrightness = [UIScreen mainScreen].brightness;
[UIScreen mainScreen].brightness = 0;
}
- (void)restoreScreen {
[UIScreen mainScreen].brightness = previousBrightness;
}
Update: It's useful to note that the brightness reported by UIScreen is only the brightness the user has set in Settings, and does not report the auto brightness adjusted value. If auto brightness is enabled, I am aware of no way to get the adjusted value.
As an example, if the user has the brightness slider at 100% in Settings but they are currently in a very dark room, then UIScreen will report a brightness of 1.0, but the true value might be closer to 0.5.
Related
I'm trying to change the radius and color of the blushing blue circle that's created around a current user's location a MapKit? After searching for answers I found an old question Change User Location Blue Pulsing Circle Radius but the answer is an old objective-C service that costs money. Is there anything new in swift that would make this task easier, or is there a way to just remove the pulsing blue circle all together
The blue color for the user location is based on the tint color of your map view, changing this will set the new color for the user location circle.
//Objective-C
mapView.tintColor = [UIColor redColor];
//Swift
mapView.tintColor = redColor()
If you wish to remove or replace the user location circle with something different you can change the didAnnotation delegate method.
-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
MKAnnotationView *usrLoc = [mapView viewForAnnotation:mapView.userLocation];
usrLoc.hidden = YES;
}
You cannot change the radius since it represents the GPS accuracy.
In swift 4,
I choosed a clear color so it is less anoying than a red or blue color to see below the map's details.
mapView.tintColor = UIColor.clear
I'm attempting to periodically change the background color of my SKScene node every 10 seconds. I'm using a SKAction to fade the SKScene background color to a new, randomly generated color, with the fade action lasting for 4 seconds. Right now, my attempted implementation uses a 'helper' SKSpriteNode to:
obtain a new background to use
set its color
apply an alpha fade action to it
and set it as the first node in my SKScene's node tree
In addition, I have some time keeping code to make sure that the background color on my SKScene is only changed once every 10 seconds. This means that if I assume SpriteKit aiming for 60FPS, the background color should be changed once every 600 seconds. Since each background color fade action should last 4 seconds, each fade should take 240 seconds (again, assuming 60FPS to keep it simple). Basically, there would be a period of 360 seconds where nothing is happening with the background color.
Anyway, I can't seem to get my code to currently work, as the color doesn't change at all. The default background color I set for my SKScene (within my init method) is RGB white. This is the only color that displays each frame. In addition, 'timeSinceUpdateCalled' and 'timeSinceTheLastBackgroundColorChange' are both initially set to 0.0
Everything is driven from the SKScene's -update:(CFTimeInterval) method. Code below:
-(void)update:(CFTimeInterval)currentTime {/* Called before each frame is rendered. Basically, any actions taken on the title scene will go in here*/
CFTimeInterval timeSinceUpdate = currentTime - self.timeSinceUpdateCalled;
self.timeSinceUpdateCalled = currentTime;
[self changeBackgroundTitleColorEverySoOften:timeSinceUpdate];
}
-(void)changeBackgroundTitleColorEverySoOften:(CFTimeInterval)timeSinceUpdate{
self.timeSinceTheLastBackGroundColorChange += timeSinceUpdate;
if(self.timeSinceTheLastBackGroundColorChange > 10.0){
self.timeSinceTheLastBackGroundColorChange = 0;
[self renderNewTitleBackGroundColor];
}
}
-(void)renderNewTitleBackGroundColor{
_batball_titlehelpersprite = [[SKSpriteNode alloc] initWithColor:self.colorGenerator size:self.view.bounds.size];
_batball_titlehelpersprite.alpha = 0.0;
SKAction* titleactioncolorfade = [SKAction fadeInWithDuration:4];
titleactioncolorfade.speed = 1.0;
[_batball_titlehelpersprite runAction:titleactioncolorfade];
[self insertChild:_batball_titlehelpersprite atIndex:1];
}
-(UIColor* )colorGenerator{//This method generates a random UIColor
UIColor* generatedColor = nil;//The generated random color
generatedColor = [UIColor colorWithRed:[BatBallUtils randomFloat2:255] green:[BatBallUtils randomFloat2:255] blue:[BatBallUtils randomFloat2:255] alpha:0.0];//Generate a random color
return generatedColor;
}
I stepped through this code, and it seems that everything should work. My UIColor generator code works as expected as well. This is the code I use to generate a random float number between 2 and 255 for RGB:
+(float)randomFloat2:(int)maxNum{//Generate a random float number between two floating point min and max numbers
float num = (arc4random() % maxNum) / (float)maxNum;
return(num);
}
Does anyone have any ideas what I'm doing wrong?
UIColor values are in the range 0.0 to 1.0, see https://developer.apple.com/library/ios/documentation/uikit/reference/UIColor_Class/Reference/Reference.html#//apple_ref/occ/clm/UIColor/colorWithRed:green:blue:alpha:
Also be sure to use 1.0 for alpha otherwise the color might not render at all because it's fully transparent.
When the screen of the iPhone orientation changes, I adjust my projection matrix of my 3D rendering to the new aspect value. However, doing this in either willRotateToInterfaceOrientation or didRotateFromInterfaceOrientation would cause the aspect ratio being wrong during the transition, because at the beginning of the animation, the screen size is still the same as before and is changed to the new bounds gradually while being rotated. Therefore I want the aspect value used for my 3D projection matrix to change gradually as well. To achieve this, I retrieve start time and duration for the rotation animation in willAnimateRotationToInterfaceOrientation:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
_aspect.isChanging = YES;
_aspect.startedChanging = [[NSDate date] retain];
_aspect.changeDuration = duration;
_aspect.oldValue = self.renderer.aspect;
_aspect.currentValue = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
}
Note that the view bound size is already set to the new value that will be valid after the animation.
Then, in update, I do the following:
- (void)update
{
if (_aspect.isChanging) {
float f = MIN(1, [[NSDate date] timeIntervalSinceDate:_aspect.startedChanging] / _aspect.changeDuration);
self.renderer.aspect = _aspect.oldValue * (1-f) + _aspect.currentValue * f;
} else {
self.renderer.aspect = _aspect.currentValue;
}
[self.renderer update];
}
This already works quite well, but the render aspect change does not match the actual aspect change, which is because I'm interpolating it linearly. Therefore I tried to match the easing of the actual aspect change by throwing math functions at the problem: The best result I could get was by adding the following line:
f = 0.5f - 0.5f*cosf(f*M_PI);
This results in almost no visible stretching of the image during the rotation, however if you look closely, it still seems to be a bit unmatched somewhere in between. I guess, the end user won't notice it, but I'm asking here if there might be a better solution, so these are my questions:
What is the actual easing function used for the change in aspect ratio during the rotation change animation?
Is there a way to get the actual width and height of the view as it is displayed during the orientation change animation? This would allow me to retrieve the in-between aspect directly.
On the first bullet point, you can use CAMediaTimingFunction (probably with kCAMediaTimingFunctionEaseInEaseOut) to get the control points for the curve that defines the transition. Then just use a cubic bezier curve formula.
On the second bullet point, you can use [[view layer] presentationLayer] to get a version of that view's CALayer with all current animations applied as per their current state. So if you check the dimensions of that you should get the then current values — I guess if you act upon a CADisplayLink callback then you'll be at most one frame behind.
Why does the UISlider view ignore the alpha view when set to 0.5?
Code:
for (int i = 0; i < 3; i++) {
UISlider *slider = [[[UISlider alloc]
initWithFrame:CGRectMake(0, i * 30, 200, 30)]
autorelease];
slider.alpha = 0.4 + (CGFloat)i / 10.0f;
[window addSubview:slider];
}
Result:
The sliders have alpha values 0.4, 0.5 and 0.6. And as you can see the middle one with 0.5 is completely opaque. It seams to only occur with alpha 0.5. Have tested other UI controllers and they work as expected with alpha is set to 0.5.
Reproduced with iOS 4.2 on real device and with iOS 3.2 and 4.2 in simulator.
BTW if someone curious how and why I hit this problem it's the sliding direction pad configuration for a puzzle game called Slippy.
As you said that other UI controllers work with 0.5 alpha, there should be no difference with UISlider, since they inherit alpha property from UIView class and there is reference to the opaque property ("You should always set the value of this property to NO if the view is fully or partially transparent"). Maybe you can try to follow the advice.
If there's really a bug with 0.5 value, you can simply change your starting transparency from 0.4 to 0.41/0.39 w/o any visible difference:
slider.alpha = 0.41f + (CGFloat)i / 10.0f;
Finally, you can output the resulting alpha values to some labels to check if they are the expected ones or output the (CGFloat)i value to see if something wrong with type casting.
I'm creating a simple color picker controlled by a custom slider type control.
I'm passing a float value from my slider to a UIColor constructor method and updating the background color of a CALayer as the value changes.
It runs really smooth in the simulator, but I get a lot of flickering when running on the device.
Is this just because it's over taxing the GPU? It's strangely the worst when moving through blue. And changing the alpha value and brightness flicker more than changing the saturation and hue.
Should I not pass arbitrary float values as the slider value changes? If not, how could I constrain this to less colors for optimization?
I thought of disabling implicit animations for the backgroundColor property of the CALayer, but I'm not sure how to do this.
Are there any tricks for optimizing UIColor changes.
Update
I'm not using drawRect: or drawInRect:
I'm just changing the backgroundColor property of a CALayer. Every time touchesMoved: is called I grab the location, create a 0.0 to 1.0 float value and pass a message to my delegate that the value has changed and call the -(void)updateCurrentColor method.
Here's an example of my implementation:
#implementation MyCustomSliderView
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
hueLocation = [[touches anyObject] locationInView:self];
//Smoothing
if ((hueLocation.x > previousHueLocation.x) && ((hueLocation.x - previousHueLocation.x) > 1.0) && (hueLocation.x - previousHueLocation.x) < 10.0) {
hueLocation.x = previousHueLocation.x + 1.0;
}
if ((hueLocation.x < previousHueLocation.x) && ((previousHueLocation.x - hueLocation.x) > 1.0) && (previousHueLocation.x - hueLocation.x) < 10.0) {
hueLocation.x = previousHueLocation.x - 1.0;
}
//Percentage of screen.
hueValue = hueLocation.x/self.bounds.size.width;
//Clip to 1.0 & 0.0
if (hueValue > 1.0) {
hueValue = 1.0;
}
if (hueValue < 0.0) {
hueValue = 0.0;
}
NSLog(#"Value is: %f", hueValue);
NSLog(#"Location %f", hueLocation.x);
previousHueLocation = hueLocation;
if([delegate respondsToSelector:#selector(updateCurrentColor)]) {
[delegate updateCurrentColor];
}
}
#implementation MyViewController
- (void)updateCurrentColor {
currentColor = [UIColor colorWithHue:hueSliderView.hueValue
saturation:saturationSliderView.saturationValue
brightness:brightnessSliderView.brightnessValue
alpha:alphaSliderView.alphaValue];
colorLayer.backgroundColor = currentColor.CGColor;
}
At first I thought that it was jumping values due to the imprecision of the touch interface. The smoothing function helped, but it still flickers some, especially with the alpha value, even when my location only changes by 1 pixel. Should I constrain this to a limited amount of colors/values instead of just passing in an arbitrary float? Again, runs great in the simulator, seems to be just a performance issue.
Disabling implicit animations eliminated the flickering.
I've updated the color changing methods so that the background color can be animated when called from touchesBegan:, but not implicitly animated when called from touchesMoved:
- (void)updateCurrentColorAnimated:(BOOL)animated {
currentColor = [UIColor colorWithHue:hueSliderView.hueValue
saturation:colorView.saturationValue
brightness:colorView.brightnessValue
alpha:alphaSlider.alphaValue];
if (animated) {
colorLayer.backgroundColor = currentColor.CGColor;
}
if (!animated) {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
forKey:kCATransactionDisableActions];
colorLayer.backgroundColor = currentColor.CGColor;
[CATransaction commit];
}
}
The reason I rolled my own slider is so that I can jump to new values instead of having to catch the little slider control perfectly, the interaction of which I found not very good.
Drawing on the iPhone is double buffered. If you are getting flickering, it is because you are drawing one thing and then another -- it is not because of speed problems.
I would guess you are making one of the following mistakes:
Updating your color value and drawing your color square out of sync (so the color is not set correctly when you drawInRect:)
Failing to initialize/calculate your color correctly (so you are displaying invalid colors)
Erasing or redrawing your rectangle when you shouldn't
Another thing to check... colors in Cocoa are floats from zero to 1. Setting integer values from 0 to 255 (as used on the web or Windows) will result in seriously weird problems.
If your color calculations are over 0 to 255, then divide by 255.0 before setting the UIColor.