How to get shadow for UIImage in iOS using objective C - ios

As can be seen in the image above there is a black shadow at the bottom of the image. I want similar effect in table view.( I want shadow for every line or the seperator between the table view cells.) The shadow effect should be more on the center as can be seen above and it should fade at its extremes.. Kindly help..

You can add a shadow by adding it to the view's layer (change the values to get your desired effect):
view.layer.shadowColor = [UIColor blackColor].CGColor;
view.layer.shadowOffset = CGSizeMake(0.0f, 2.0f);
view.layer.shadowOpacity = 0.5f;
view.layer.shadowRadius = 4.0f;
As you mentioned, you want to use it inside a UITableView, then you should provide a shadowPath as well for the best performance:
- (void)layoutSubviews
{
[super layoutSubviews];
view.layer.shadowPath = [UIBezierPath bezierPathWithRect:view.bounds].CGPath;
}

Related

How to Set The Length Size of A UIButton Border Programmatically

I need to set the length size of a UIButton border. I tried using this
[[jb layer] setBorderLength:2.2f];
but got a error saying "setBorderLength is not a method".
Here's my code for my UIButton border:
[[jb layer] setBorderWidth:2.2f];
[[jb layer] setBorderColor:[UIColor blackColor].CGColor];
setting a layer border parameters :
jb.layer.borderColor = [UIColor blackColor].CGColor;
jb.layer.borderWidth = 1;
jb.layer.cornerRadius = jb.bounds.size.width * 0.1;
There is no border length. The border width determines how thick your border is.
The border is around your frame. If you mean your border to be appear wider around your button consider changing the frame.
You would have to create layers and add it to the button to handle this scenario
CALayer * layer = [CALayer layer];
layer.bounds = CGRectMake(0, 0, buttonWidth, 1.0);
layer.backgroundColor = [UIColor blackColor].CGColor;
layer.opacity = 0.1f;
[self.button.layer addSublayer:layer];
This will add border on only the top border of button.
Change the frame and add 3 more layers to cover left right and bottom

Add border to bottom of .xib (objective-c)

I am trying to only add a border to the bottom of my .xib view. I currently have the following code which places a red border on ALL FOUR sides. I only want the border to be on ONE side, the bottom... How do I set the border to the bottom?
Current Code for class that controls .xib:
- (void)awakeFromNib {
self.contentView.layer.borderWidth = 5.0f;
self.contentView.layer.masksToBounds = YES;
self.contentView.layer.borderColor = [UIColor redColor].CGColor;
}
This is what I get:
CALayer *bottomBorder = [CALayer layer];
bottomBorder.borderColor = [UIColor redColor].CGColor;
bottomBorder.borderWidth = 1;
bottomBorder.frame = CGRectMake(0, self.contentView.frame.size.height - bottomBorder.borderWidth, self.contentView.frame.size.width, bottomBorder.borderWidth);
[self.contentView.layer addSublayer:bottomBorder];
If you don't know how to make a view that draws a red border at its bottom, then why not just make a red subview and pin it to the bottom?

Can't set shadow on UICollectionViewCell and have rounded corners. Can only make one work at a time

I have a UICollectionViewCell subclass and I need to round its corners and add a shadow as well. The cell looks like a square card, and the cells have a good amount of space in-between them.
So "underneath" every cell, I would like to add some shadow. I can successfully do this, but then my cell only has rounded corners on the bottom. The top just has normal corners. I need rounded corners for all four corners.
I have found solutions on here for UIViews that recommend adding a separate UIView as a subview, but I would prefer to avoid this for performance reasons.
I did find one solution which was to use this method which you will find in my code below:
[UIBezierPath bezierPathWithRoundedRect: cornerRadius:]
But that didn't work for me either. Is it possible that it's not working for me because of how I'm trying to only add the shadow "underneath" / at the bottom of the cell? It seems like most of these answers are provided for questions where the developer wants to add a shadow around the entire cell.
I guess I would be willing to add a special subview to my UICollectionViewCell subclass, but I would like to use that as a last resort.
I am targeting iOS 7+ and using Xcode 6.1.1.
Here is the code I am using inside my UICollectionViewCell subclass to try and achieve both the shadow and the rounded corners:
- (void)load:(CustomUserObject *)customObject
{
self.customObject = customObject;
// Round cell corners
self.layer.cornerRadius = 12;
// Add shadow
self.layer.masksToBounds = NO;
self.layer.shadowOpacity = 0.75f;
self.layer.shadowRadius = 10.0f;
self.layer.shouldRasterize = NO;
self.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(self.frame.size.width/2 - (self.frame.size.width - 50)/2, self.frame.size.height, self.frame.size.width - 50, 10) cornerRadius:self.layer.cornerRadius].CGPath;
}
EDIT: If I set self.layer.masksToBounds to NO, the shadow works but the top corners do not round. If I set self.layer.masksToBounds to YES, the shadow does not work, but all four corners are now rounded. I just can't figure out how to round all four corners and get the shadow to work.
After looking at the sample project that Timothy Moose was kind enough to share in the comments, I realized that I was literally doing everything almost exactly like he was.
Out of frustration, I revisited my cell's nib file and it finally hit me. I had added a UIView to the top of the cell. This view was serving as a colored banner and was also functioning as a container for another UIImageView and a UILabel.
The top of the UICollectionViewCell was successfully rounding the top corners, but you never would have known because the colored UIView was at the top of the cell and was just as wide as the cell.
Stupid mistake, many times its the little things.
Here is the final code I am using to achieve four rounded corners and a shadow underneath the UICollectionViewCell. self.banner is the extra UIView that was hiding the cell's top corners:
- (void)load:(CustomUserObject *)customObject
{
self.customObject = customObject;
// Round the banner's corners
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.banner.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(10, 10)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.banner.bounds;
maskLayer.path = maskPath.CGPath;
self.banner.layer.mask = maskLayer;
// Round cell corners
self.layer.cornerRadius = 10;
// Add shadow
self.layer.masksToBounds = NO;
self.layer.shadowOpacity = 0.75f;
self.layer.shadowRadius = 10.0f;
self.layer.shouldRasterize = NO;
self.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(self.frame.size.width/2 - (self.frame.size.width - 50)/2, self.frame.size.height, self.frame.size.width - 50, 10)].CGPath;
}
func dropShadow() {
self.layer.masksToBounds = false
self.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
self.layer.shadowOpacity = 0.5
self.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
self.layer.shadowRadius = 4.0
self.layer.cornerRadius = 5.0
}
//To drop shadow use
cell.dropShadow()

add shadow to a layer

I can add shadow to imageView layer using the following code.
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.png"]];
self.imageView.center = self.view.center;
CALayer *containerLayer= [CALayer layer];
containerLayer.shadowColor = [UIColor blackColor].CGColor;
containerLayer.shadowRadius = 10.0f;
containerLayer.shadowOffset = CGSizeMake(10.0f, 5.0f);
containerLayer.shadowOpacity = .8f;
[containerLayer addSublayer:self.imageView.layer];
[self.view.layer addSublayer:containerLayer];
1 . The problem is that I don't know why I have to add imageView.layer to containerLayer to get the imageView shadow effect. However, if I add containerLayer to imageView.layer, there's no shadow in imageView, why?
The error code is:
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.png"]];
self.imageView.center = self.view.center;
CALayer *containerLayer= [CALayer layer];
/*same as before*/
[self.imageView.layer addSublayer:containerLayer];
[self.view.layer addSublayer:self.imageView.layer];
Question2: the containerLayer's(used to provide shadow to imageView) frame = {{0, 0}, {0, 0}}, but the final position is in the center of screen. why?
A layer needs something opaque inside it to create a shadow around (unless you've specified a shadowPath explicitly). So your first version of the code works because the containerLayer has the imageView's layer as a sublayer. But, as you noticed from Question #2, the containerLayer's frame indicates that it is actually located in the upper left corner with a size of (0,0). The reason you can still see the image is that containerLayer is not masking to its bounds. Add this line to your first version, and the image disappears:
[containerLayer setMasksToBounds: YES]; // kitten (and shadow) is gone
Your version #2 of the code does not display a shadow because, in part, the containerLayer does not "contain" anything. If you use version #2 but give the containerLayer a new frame and an opaque background color, a shadow appears. (But this obviously isn't a solution, because the image is covered up...) Also note that there is no shadow when the layer's background is [UIColor clearColor].
[self.imageView.layer addSublayer:containerLayer];
containerLayer.frame = self.imageView.layer.bounds;
containerLayer.backgroundColor = [UIColor yellowColor].CGColor; // yellow box w/shadow
// containerLayer.backgroundColor = [UIColor clearColor].CGColor; // no shadow here
If you wanted to have a container with a shadow that houses the UIImageView, you could do something like this:
UIView * shadowView = [[UIView alloc] initWithFrame: self.imageView.frame];
shadowView.layer.shadowColor = [UIColor blackColor].CGColor;
shadowView.layer.shadowRadius = 10.0f;
shadowView.layer.shadowOffset = CGSizeMake(10.0f, 5.0f);
shadowView.layer.shadowOpacity = .8f;
[self.view addSubview: shadowView];
self.imageView.frame = (CGRect) { CGPointZero, self.imageView.frame.size };
[shadowView addSubview: self.imageView];
A CALayer could be used instead of a UIView in a similar way. Or you could apply shadow attributes to the imageView's layer directly, making sure that neither the view nor the layer is clipping/masking to bounds.
If you want to add a shadow over the imageview just change the alpha value (0.0 min - 1.0 max) of that imageview. This will give you the shadow effect and whenever you want to remove the shadow just restore the alpha value to 1.0.
For ex:
self.imageview.alpha = 0.5 // shadow state
self.imageview.alpha = 1.0 // original state

UITableView with shadow and corner radius (movie example attached)

I have a UIViewController with a UITableView. The sits inside the view controller's view with some padding on all sides. I am trying to draw a drop shadow from the table view as well as rounded corners, but I am unable to achieve both at the same time. I have tried with the following code and turned masksToBounds on and off, but setting it to NO create a really weird effect with the shadow scrolling and the calls are not clipping inside the table.
[self.tableView.layer setShadowColor:[UIColor blackColor].CGColor];
[self.tableView.layer setShadowOffset:CGSizeMake(0, 3)];
[self.tableView.layer setShadowOpacity:0.4];
[self.tableView.layer setShadowRadius:3.0f];
[self.tableView.layer setCornerRadius:5.0f];
[self.tableView.layer setShadowPath:[[UIBezierPath bezierPathWithRoundedRect:self.tableView.bounds cornerRadius:5.0f] CGPath]];
I am just drawing a UITableView with plain style too. The effect I am trying to achieve can be seen in the free app Transit App and here's a movie where you can see the shadow stays and the table even has a mask that scrolls up and down.
I have searched and searched and haven't been able to put together a solution based on other SO answers or online articles. Help appreciated.
Try the below links, some of them are old but you can get some pointer.
Custom Table Effects
Dropshadow 2
Cool Table Views
DropShadow
Okay!! I attempted once again and got an effect, it is again a work around only (instead of using images), the below is what i tried
Create a CALayer, with the same frame as your tableview, give the same curve and all, add the table view on top of this layer, thats it.
CALayer *sublayer = [CALayer layer];
sublayer.backgroundColor = [UIColor blueColor].CGColor; // If you dont give this, shadow will not come, dont know why
sublayer.shadowOffset = CGSizeMake(0, 3);
sublayer.shadowRadius = 5.0;
sublayer.shadowColor = [UIColor blackColor].CGColor;
sublayer.shadowOpacity = 1.0;
sublayer.cornerRadius = 5.0;
sublayer.frame = CGRectMake(myTable.frame.origin.x, myTable.frame.origin.y, myTable.frame.size.width, myTable.frame.size.height);
[self.view.layer addSublayer:sublayer];
[self.view.layer addSublayer:myTable.layer];
Ah!! due to some reason I am unable to upload the screenshot from my machine, firewall ;-). I will try from my home.
-anoop
It is recommended to use images for drop shadows with large tableviews, all that drawing has the ability to slow down performance, which can result in bad user experience, just a word of advice
I know this is a rather old question, but I recently had the same problem and the solutions here were good examples, but not full enough. So here it is the method I'm using to create shadow of a table view. It can be used also for any other view.
-(void)makeShadowToView:(UIView*) view withHeight:(CGFloat)shadowHeight
{
CGRect bounds = view.frame;
bounds.size.height = shadowHeight;
view.clipsToBounds = NO; // Without this row it doesn't display any shadow, at least for a table view
view.layer.shadowColor = [UIColor blackColor].CGColor;
view.layer.shadowOpacity = 0.9f;
view.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
view.layer.shadowRadius = 5.0f;
view.layer.shadowPath = [UIBezierPath bezierPathWithRect:bounds].CGPath;
}
Example usage: [self makeShadowToView:self.view withHeight:height];
where height is added in case you want to recalculate the shadow's height according to the table content's height.
(void)shadowForView{
CALayer *layer = self.viewActionMenu.layer;
layer.shadowOffset = CGSizeMake(-2, 0);
layer.shadowColor = [[UIColor blackColor] CGColor];
layer.shadowRadius = 2.0f;
layer.shadowOpacity = 0.80f;
// [self.view bringSubviewToFront:self.actionView];
}
And Call:
[self shadowForView];
Try this
UITableView * objTableview=[[UITableView alloc]initWithFrame:CGRectMake(x, y, w, h)];
UIView * objViewShadow=[[UIView alloc]initWithFrame:objTableview.bounds];
objTableview.layer.cornerRadius=5;
// add shadow
objViewShadow.layer.shadowOffset = CGSizeMake(0, 3);
objViewShadow.layer.shadowRadius = 5.0;
objViewShadow.layer.shadowColor = [UIColor blackColor].CGColor;
objViewShadow.layer.shadowOpacity = 0.8;
[objViewShadow addSubview:objTableview];
[self.view addSubview:objViewShadow];
You need to set this two properties
self.tableView.clipsToBounds = NO;
self.tableView.layer.masksToBounds = NO;

Resources