iOS: Accessibility Label for CALayer - ios

I want to add accessibilityLabel for some of my CALayer's.
Here is the example:
CALayer *testLayer = [CALayer layer];
[self.view.layer addSublayer:testLayer];
testLayer.backgroundColor = [UIColor purpleColor].CGColor;
testLayer.isAccessibilityElement = YES;
testLayer.accessibilityLabel = #"Some text";
testLayer.frame = CGRectMake(0, 300, 100, 100);
This approach doesn't work for me. Is it possible to make accessibility working for CALayers?
I don't want to use accessibility container in superview (there is complex hierarchy)
Thank you!

AFAIK, A custom view built from CALayers does not have support for accessibility so I guess simple answer to your question would be no! You might want to check Apple's guidelines to create Accessibility for Dynamic Elements.

Related

Set CALayer as SCNMaterial's diffuse contents

I've been searching all over the internet over the past couple of days to no avail. Unfortunately, the apple documentation about this specific issue is vague and no sample code is available (at least thats what I found out). What seems to be the issue you may ask...
I'm trying to set a uiview's layer as the contents of the material that is used to render an iPhone model's screen (Yep, trippy :P ). The iPhone's screen's UV mapping is set from 0 to 1 so that no issue persists in mapping the texture/layer onto the texels.
So, instead of getting this layer to appear rendered on the iPhone, same as left image, Instead, I get this rendered onto the iPhone like right image
Correct Render                                        Incorrect Render
Also note, that when I set a breakpoint and debug the actual iPhone node and view it in Xcode, a completely different render is shown and the layer gets half-fixed when I continue execution:
Now then... HOW do I fix this issue??? I've tried playing with the diffuse's contents transform matrix but nothing gets fixed. I've also tried resizing the UIView to 256x256 (since the UV seems to be 256x256 as shown in blender - the 3d modelling package), but that doesn't fix anything.
Here is the code for the layer:
UIView *screen = [[UIView alloc] initWithFrame:self.view.bounds];
screen.backgroundColor = [UIColor redColor];
UIView *temp = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screen.bounds.size.width, 60)];
temp.backgroundColor = [UIColor colorWithRed:0 green:(112.f/255.f) blue:(235.f/255.f) alpha:1];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectInset(temp.bounds, 40, 0)];
label.frame = CGRectOffset(label.frame, 40, 0);
label.textColor = [UIColor colorWithRed:0 green:(48.f/255.f) blue:(84.f/255.f) alpha:1];
label.text = #"Select Track";
label.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:30];
label.minimumScaleFactor = 0.001;
label.adjustsFontSizeToFitWidth = YES;
label.lineBreakMode = NSLineBreakByClipping;
[temp addSubview:label];
UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(0, temp.bounds.size.height - 2, temp.bounds.size.width, 2)];
separator.backgroundColor = [UIColor colorWithRed:0 green:(48.f/255.f) blue:(84.f/255.f) alpha:1];
[temp addSubview:separator];
[screen addSubview:temp];
screen.layer.contentsGravity = kCAGravityCenter;
Edit
What's even weirder is that if I capture a UIImage of the view using:
- (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
and use that as the diffuse's content... everything works out perfectly fine?! It's really weird and frustrating since the image's size is exactly the same as the uiview's...
Edit 2
I ended up just using an image of the view as the texture, which makes things much more static than I needed. I won't set this as the answer because I'll still be waiting for a correct fix to this issue even if it in a long time. So, if you have an answer and this topic has been opened for a long time, please bump it if you can. The documentation on this section is just so poor.
New post on an old thread, but this day-in-age, it's possible to set the UIView itself as SCNMaterialProperty (diffuse) contents. Intention to support this feature is communicated directly from SceneKit engineering at Apple, though the documentation has not yet been updated to reflect it.
To tied back to the original post, do not set a UIView.layer as material property contents; instead set contents to the UIView itself.
[Update: according to Lance's comment below, support for views may be getting worse rather than getting better.]
The SceneKit docs pretty strongly suggest that, while there are cases where you can use animated CALayers as material content, that doesn't include UIView layers:
SceneKit cannot use a layer that is already being displayed elsewhere (for example, the backing layer of a UIView object).
That suggests that if you want to make animated content for your material, you're better off with either Core Animation used entirely on its own or SpriteKit.

Making transparent Circles in iOs

I want to create a black UIView with transparent circles.
I think about create one view (with black color and transparence 50%), and add multiple circles inside of it, but I don't know how to set the transparence for each. I know how to create a circle View (an example: how to draw a custom uiview that is just a circle iphone-app).
I want to do is something like iShowcase library but with multiple dots:
Any clue? thanks.
SOLVED
I took a look to the code of iShowcase library and I solved my probblem. now, I am working in a library based in iShowcase library.
I will post here when I finish it.
Please have a look of below link hope this will helpful for you.
Link : Here is Answer to set shadow in your view.
Use alpha for your circleView. As in your link example,then add as subviews in yourmainview:
UIView *circleView = [[UIView alloc] initWithFrame:CGRectMake(10,20,100,100)];
circleView.alpha = 0.5;
circleView.layer.cornerRadius = 50;
circleView.backgroundColor = [UIColor whiteColor];
[yourmainview addSubview: circleView];
Btw in your picture I think white circles have 100% alpha. You can use individual alpha for each circleView, or use a randomizer :)
As for updated example why don't you add more buttons and showcase in your h file, synthesize them and use multiple instances .... showcase setupShowcaseForTarget:btn_custom_1 title:#"title" details:#"other"]; ? I think you should modify main classes, becouse what you want are different containerView for multiple views [circles].
Using modifyed iShowcase.m [- (void) calculateRegion], and different views as containers, I was able to make something like: http://tinypic.com/view.php?pic=2iwao6&s=8#.VLPTRqYsRE8 So the answer is: use custom views for multiple showcase [ex [showcase2 setContainerView:self.view2];], then custom frame for each showcase [ showcase2.frame = CGRectMake(0,0,100,100);] I don;t habe time to fine tuning the example, but yes, you can achieve desired result...
I finally solved my question inspired by iShowCase library I did this simple class and Upload to github.
https://github.com/tato469/FVEasyShowCase
Simplest what you can do is to have your main view (black 50% transparant) and add shapes to the mask layer of that.
So basically:
//Set up your main view.
UIView* mainView = [UIView new];
mainView.backgroundColor = [UIColor blackColor];
mainView.alpha = 0.5;
UIView* circle1 = [YourCircleClassHere new];
UIView* circle2 = [YourCircleClassHere new];
UIView* circle3 = [YourCircleClassHere new];
UIView* container = [UIView new];
[UIView addSubview:circle1];
[UIView addSubview:circle2];
[UIView addSubview:circle3];
//Make a new layer to put images in to mask out
CALayer* maskLayer = [CALAyer layer];
//Assign the mask view to the contents layer.
maskLayer.contents = (id)container;
//This will set the mask layer to the top left corner.
maskLayer.frame = CGRectMake(0,0,container.frame.size.width,container.frame.size.height);
//Lastly you assign the layer to the mask layer of the main view.
mainView.layer.mask = maskLayer;
//Applies basically the same as clipToBounds, but a bit reversed..
mainView.layer.mask = true/false;
On a sidenote:
I achieved this with images "contents = (id) [UIImage CGImage]", but I'm sure it should work with UIViews as well.
Also mind some mistakes, since I just wrote this from my mind, also I didn't test this out.. So keep me updated if it works/!works ^_^

How to set shadow gradient image on UIImageView iOS

Hey I'm new to iPhone and I have been trying to set shadow for UIImageView using shadow gradient image i.e. "Image-Shadow.png" using below code.
imageView.layer.shadowColor = [UIColor colorWithPatternImage:[UIImage
imageNamed:#"Image-Shadow.png"]].CGColor;
imageView.layer.shadowOffset = CGSizeMake(0, 1);
imageView.layer.shadowOpacity = 1;
imageView.clipsToBounds = NO;
imageView.layer.shouldRasterize = YES;
My problem is, i am not getting shadow in my UIImageView using above code. Can you please tell me that is this the correct way to add shadow image in UIImageView or it is possible with some other way?
Problem is with the image. I don't think you can provide a pattern image to create a shadow!
Give a proper color like [UIColor blackColor].CGColor and it should work.
The problem is with this line:
imageView.layer.shadowOffset = CGSizeMake(0, 1);
where you are setting the shadow, but not giving it a visible space to display itself.
Positive or negative values should be given to both parameters.
Positive values stretch "down" and "to the right" of your view, negative values stretch "to the left" and "to the up" of your view.
here is my solution as per my requirement :
//set shadow gradient on image view
UIView *shadowView = [[UIView alloc] initWithFrame:imageView.frame]; //add view behind the image view
shadowView.layer.contents = (id) [UIImage imageNamed:#"Image-Shadow.png"].CGImage;
[imageView addSubview:shadowView];
Thanks to all.

Is UICollectionView.backgroundView broken

I'm writing something relatively simple, or so I thought.
Firstly, the code, for which I'm trying to place an image on the background of the UICollectionView if there are no results returned from my server. The image is 200 by 200:
UIView *myView = [[UIView alloc] initWithFrame:self.view.bounds];
CGRect myViewSpace = self.view.bounds;
CGFloat myX = (myViewSpace.size.width /2.0) - 100;
CGFloat myY = (myViewSpace.size.height /2.0) - 100;
UIImageView *imView = [[UIImageView alloc] initWithFrame:CGRectMake(myX, myY, 200, 200)];
imView.image = [UIImage imageNamed:#"imNotHome"];
[myView addSubview:imView];
myCollectionView.backgroundView = myView;
Once there are results, I want to be able to remove it.
I thought it'd be as simple as placing the following, before I reloaded the UICollectionView:
[myCollectionView.backgroundView removeFromSuperview];
However, it appears to be doing nothing.
Am I missing something?
Thanks in advance!
It should be done this way instead:
myCollectionView.backgroundView = nil;
Explanation: You should unset the UICollectionView's background in the same way as you set it. You didn't set it by manipulating the view hierarchy, but by setting the background property. You did call addSubview in the previous line, but that was to add a subview to your background view, not to add the background view itself.
Edit:
There is a very good article about this UICollectionView bug here:
http://blog.spacemanlabs.com/2013/11/uicollectionviews-backgroundview-property-is-horribly-broken/
The solution the author gives is to reset the background to an empty opaque view:
UIView *blankView = [UIView new];
blankView.backgroundColor = [UIColor whiteColor];
[myCollectionView.backgroundView removeFromSuperview];
myCollectionView.backgroundView = blankView;
Also, the author recommends not using the backgroundView property at all but doing it yourself:
Frankly, I think the best solution is to just ignore the backgroundView property all together. Instead, make the collection view’s background clear, and implement your own backgroundView; just throw a view behind the collection view.

Set rounded corners globally on UIButtons in iOS application

Is there a way to set UIButtons with rounded corners globally like with color below?
[[UIButton appearance] setBackgroundColor:[UIColor purpleColor]];
The list of properties that you can set using UIAppearance is found here:
What properties can I set via an UIAppearance proxy?
Unfortunately rounded corners are not something that is possible.
You could use something like beautify (https://github.com/beautify/beautify-ios) which enhances the UIKit controls to allow you to specify rounded buttons.
With beautify, the following would give you rounded buttons globally:
BYTheme *theme = [BYTheme new];
theme.buttonStyle.border = [[BYBorder alloc] initWithColor:[UIColor blackColor]
width:2.0f
radius:5.0f];
[[BYThemeManager instance] applyTheme:theme];
I've found this link. Please see if it could help.
Taming UIButton
It is using this
[[basicButton layer] setCornerRadius:18.0f];
As i mentioned in previous answer. You have to subclass UiButton for it.. :)
#import <QuartzCore/QuartzCore.h>
Add this in your header file.
then in implementation,
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 100, 100,50);
[btn setTitle:#"Hello" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor colorWithRed:128.0/255.0f green:0.0/255.0f blue:0.0/255.0f alpha:0.7]];
btn.frame = CGRectMake(100.0, 100.0, 120.0, 50.0);//width and height should be same value
btn.clipsToBounds = YES;
btn.layer.cornerRadius = 20;//half of the width
btn.layer.borderColor=[UIColor redColor].CGColor;
btn.layer.borderWidth=2.0f;
cornerRadius will do the trick for you.. Let me know if more info needed.. :)
Edit
This cannot be achieved globally. As you used appearence, here is the list to see what you can customize with UIAppearance. what you can do is you can create a subclass of your UIButton, & there you can write implementation of setCornerRadius in initWithCoder Method.
Migrating advice for a workable solution to Swift (it's also possible using an equivalent ObjC category on UIView):
1. Add this extension https://gist.github.com/d3ce2e216884541217d0
2. Code:
let a = UIButton.appearance()
a.layerCornerRadius = 20.0
a.layerBorderColor = UIColor.redColor().CGColor
a.layerBorderWidth = 2.0
This sort of hack works because of how properties are copied. All appearance changes to things like a.layer and a.titleLabel are not propagated, but extension properties are copied.

Resources