iOS controlling UIView alpha behaviour for subviews - ios

In my example, I have 3 views: one red view containing two white views. I change the red container view's alpha to 0.3 and this happens (look at the image, the current result).
By seeing this, I can only assume (tell me if I'm wrong) that setting a view's alpha will also set all of its subviews' alphas. My question is : is there a way to simply tell the red view to act as a whole so that setting its alpha would give something that looks like the wanted result (in the image)?
This is what it looks like without any alpha :

To elaborate on Mark's answer: If you set UIViewGroupOpacity in the Info.plist, it will change the behavior for all views in your app, if you are interested in only fixing the rendering of this particular view, you could also use this snippet:
redContainerView.layer.shouldRasterize = YES;
// No setting rasterizationScale, will cause blurry images on retina.
redContainerView.layer.rasterizationScale = [[UIScreen mainScreen] scale];

The iOS alpha property is inherited by its subviews. If we are setting alpha 0.3 for red view then both subview will have the alpha = 0.3. There is no way to stop subviews from inheriting their alpha value from their superview.
The solution might be to set the colour of the red view with an alpha of 0.3. The color property will not be inherited by its subview.
[redView setBackgroundColor:[UIColor colorWithHue:238.0f/255.0f saturation:24.0f/255.0f brightness:24.0f/255.0f alpha:0.3]];

Check out the possible UIKit keys for Info.plist, specifically UIViewGroupOpacity.
UIViewGroupOpacity (Boolean - iOS) specifies whether Core Animation
sublayers inherit the opacity of their superlayer.
Info.plist UIKit Keys

Related

UITableView text color blur issue

I have two UITableViews. One of the tables is working fine but the UILabels in the other table is blurry. I have tried changing their color programmatically. It can change the color ex: black to green but the blurry issue still remains.
This is my hierarchy of this particular view
How can I make the text clear like the first table?
You might have changed the alpha value of any of the superviews of UITableView. If you changed a view's alpha value, it affects all the subview's alpha
Set shouldRasterize = false on the CGLayer of the view containing the UILabel.
And
Your label is blurry because the frame is using floating numbers.
To force integers value for your frame just do :
[loadingText setFrame:CGRectIntegral(loadingText.frame)];

Round UIVisualEffectView

I have a map. On the map, I'd like to draw small, blurred circle. I've implemented something like this:
UIVisualEffect *visualEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
self.visualEffectView = [[UIVisualEffectView alloc] initWithEffect:visualEffect];
[self addSubview:self.visualEffectView];
and then in layoutSubviews:
[self.visualEffectView setFrame:CGRectMake(0.f, 0.f, 20.f, 20.f];
Now the problem is making this view round. I've tried:
[self.visualEffectView.layer setCornerRadius:10.f];
However nothing happens. Another try was with (basing on SOF question):
CAShapeLayer *mask = [CAShapeLayer layer];
mask.path = [UIBezierPath bezierPathWithOvalInRect:self.visualEffectView.bounds].CGPath;
self.visualEffectView.layer.mask = mask;
But in this case, the visualEffectView is round but doesn't blur :/. Is there any way to make it working?
BTW: I've tried FXBlurView, however it works very slowly, I can't accept my app to load only map + blur for ~1 minute on iPhone 5.
Tryout:
self.visualEffectView.clipsToBounds = YES;
Put this after you set the cornerRadius. This should be it. You can leave out the BezierPath stuff. Hope this helps :)
EDIT:
I just tried something similar in my own project. And a good way to keep the blur with round corners, is simply to put the visual effect view as a child of a new view with the same frame as your visual effect view. You can now just set the corner radius of this new parent UIView object and set its clipsToBounds property to YES. It then automatically gives its subviews the corner radius, as it clips to its bounds.
Give it a try, it works in my case.
I figured this out if anyone wants to know how to do it, no code needed:
Create a view and set its background to "Clear Color" in the Attribute editor (it MUST be clear color not default.
Drag another view on top of the first view, size it to the size you want your Visual Effect view to be, and in the Attribute editor set its background to "Clear Color", and check "Clip Subviews".
Also on this view, go to the identity inspector and under "User Defined Runtime Attributes" add a new Key Path named "layer.cornerRadius", make it type "Number", and set its value to 9 or higher for a decent rounded edge. (There's a bug in Xcode which will change the Key Path back to the default once you change the Type, if this happens, just be sure to go back and re-type in layer.cornerRadius).
Drag a Visual Effects View with blur on top of the View in step 3.
Now run your program. You will have rounded edges, blur, and no artifacts.
Now, I created mine where it links using a segue, if you need this to work with a segue your segue has to be set to Modal and the presentation has to be set to OVER Full Screen (not just Full Screen).
Here is a link to a project file that demonstrates it. Note the hierarchy of the views in the second view controller: Project File on Dropbox
EDIT: My picture disappeared so I readded it.
Things have obviously changed since the original question, but I was able to achieve this just by selecting "Clip to Bounds" and setting "layer.cornerRadius" in "User Defined Runtime Attributes" on the Visual Effect View itself.
to draw circle the CornerRadius must be equal width/2
in your example width = 30 then the CornerRadius = 30/2 = 15;
This works for me
#IBOutlet weak var blurView: UIVisualEffectView!
And in viewDidLoad()
blurView.layer.cornerRadius = 10;
blurView.clipsToBounds = true
You can change the corner radius according to your preference.
Well, so there is a possibility to apply rounded corners just like on normal UIView. However the UIVisualEffectView won't look good, because the area nearby curved 'sides' of the circle isn't blurred properly. Because it looks buggy and ugly I disadvise to round UIVisualEffectView.

Can the invisible outline borders of controls in xcode be viewed?

Sorry I'm not sure if I have the terminology correct but I'd like to see the borders of the controls I use in Xcode as I work with them on my storyboard.
For example, I have a UITextView but I'm unable to see how much space it takes up until I click it.
I'm convinced there's an option for it and a google hasn't turned up anything, probably because I'm searching for the wrong thing!
Thanks in advance.
In Xcode, Editor > Canvas > Show Layout Rectangles will draw a red rectangle around each view, and the baseline for views where that makes sense.
You can see the bounds of any view in the screen using this code:
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 1.f;
Look you can use this for ANY view you want. Also, you can change the color and border size if you need.
If you can't see the bounds, check out if your view hasn't ambiguously layout or if the frame has defined correctly.
If you do not want to use code to do this you can go into the Interface Builder and click on the desired object and in the Attribute Inspector set the background to any color. This will not give you a border, but rather a filled rectangle over the whole area of the object which will allow you to see the objects bounds.

Mistake in iOS documentation regarding UIView's alpha property?

I just noticed something weird in the UIView's class reference. Under alpha it states:
This value affects only the current view and does not affect any of its embedded subviews.
But as you most certainly know, that is not the case. If you change the alpha of a superview all subviews also apply the new alpha.
Is it a mistake in the documentation or am I misunderstanding it?
This value affects only the current view and does not affect any of its embedded subviews.
I understand this as:
Changing the alpha value on a view will not change the alpha value on any subviews. As in, whilst the subviews will appear to have changed their alpha, their .alpha property value will not change when the superview's .alpha is changed.

UIView group opacity in single view heirachy

I am writing a UI library in which i would like to be able to have the alpha of the UIViews as if the UIViewGroupOpacity info.plist ket was set. See following links:
Make UIView and subviews translucent as one layer, not individually
iOS controlling UIView alpha behaviour for subviews
But, as I am writing a lib, I dont want the projects to have to set this global key, and effect the behaviour of the main project.
Is there any other way of achieving this? I dont want to cycle through all the subviews and set alpha of each subview, as the project that includes my lib might have this key enabled...
Yes there is, you can set shouldRasterize of the view's layer.
containerView.layer.shouldRasterize = YES;
// Not setting rasterizationScale, will cause blurry images on retina displays:
containerView.layer.rasterizationScale = [[UIScreen mainScreen] scale];
This will have the same effect as UIViewGroupOpacity but only for containerView and it's subviews.
For iOS 7.0 and later:
Since iOS 7.0, this can be controlled for each CALayer individually through the allowsGroupOpacity property. By setting it to YES, you get the same behavior as if UIViewGroupOpacity was set, but just for that particular layer.

Resources