I have a UIImage inside a UITableViewCell.
What is the best way to have upper and lower borders around the UIImage?
[cell.backgroundImageView.layer setBorderColor: [[UIColor blackColor] CGColor]];
[cell.backgroundImageView.layer setBorderWidth: 2.0];
cell.backgroundImageView.layer.frame = CGRectMake(0, 0, cell.backgroundImageView.layer.frame.size.width + 10, cell.backgroundImageView.layer.frame.size.height);
Doesn't seem to work.
The border properties manage a border around the whole layer, not a partial one.
I'd go with a couple of UIViews (with their background color set as needed), pinned to the UIImageView using autolayout and pinned within the cell frame. In that way you don't risk drawing the borders outside the bounds of the cell, or having your other cell content mis-aligned to the image, since the image appears to be a certain size but it actually larger because you have been playing with the layers.
If performance is not a consideration you can add a UIView with 1px height above and below the image and set its background color.
Related
I am trying to add shadow to an UIImage that is inside a UITableViewCell. I configured image using UIBezierPath to draw a shadow around its bounds. The shadow appear on either side of the image but the shadow on the top of image is clipped by the table view cell's border because there is no space between image's top and the table cell's border. I cannot have space between image's top and border because these cells are collapsible and will clip lower parts of the image to make it look like a carousel of cards stacked one on the top of another. Here is the code I am using to generate shadows:
let shadowPath = UIBezierPath(rect: self.bounds)
layer.masksToBounds = false
self.clipsToBounds = false
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowOffset = CGSizeMake(0.0, -3.0)
layer.shadowOpacity = 0.1
layer.shadowRadius = 0.56
layer.shadowPath = shadowPath.CGPath
Here is a screenshot of what I'm trying to achieve:
What I've done so far is dynamically load table cells with images of cards, hide overflow of image that are greater than the height of the cells, increase height of cells on tap so that the tapped card pushes other cards below it by increasing the height of the cell and come to full view mode.
The problem is the shadows on top of the card gets hidden because maybe it tresspasses into the cell above it?
I understand that my entire approach might be wrong on this one, so I'm open to any suggestions. Please help.
UPDATE
https://github.com/gleue/TGLStackedViewController -> TGLStackedViewController
This view controller is exactly what I want plus shadows on top. Now I've come to realize that I do not need to render shadows while viewing but adding shadows while saving image will do. It is more efficient as well because the app does not have to draw the shadows every time the image is being displayed The problem however, is, this library is written in ObjC and is compatible with iOS9+ only.
I can currently change the cell's entire border width and color, but not just one side of the border.
Are you using the border attributes on CALayer? Those always apply to all sides.
To have just one border in a specific width and color you should add a CALayer with the right size, location and color as sub layer to your cell.
The easiest method I came across for changing just one side of the border is to use a UIView with its height set to the width of the border you want then align properly.
UIView *topBorder = [UIView alloc] initWithFrame:CGRectMake(0, 0, view.frame.size.width, 4);
topBorder.backgroundColor = [UIColor blackColor];
[view addSubview:topBorder];
in my app the UITableViewCell size are dynamic which means each has it's own height. inside of each cell there is a background image in a UIImageView. Through storyboard, i used autolayouts to customize the UIImageView to automatically stretch as the cell is stretched. The problem is that when they stretch the whole image stretches with the corners. So i was looking up online and i came over using resizableImageWithCapInsets: in order to stretch the stretchable sides and exclude the unwanted ones. So i tried the following code in tableView: cellForRowAtIndexPath: as i wanted the image to be stretched vertically only (height):
[cell.backgroundImage.image resizableImageWithCapInsets:UIEdgeInsetsMake(16, 0, 16, 0)];
however, the problem persisted as in the picture below
As you can see, the image corners are still stretched. What am i doing wrong? is the edgeInset values wrong? or should i place the code somewhere else ?
You create UIEdgeInsets values using the UIEdgeInsetsMake() function. UIEdgeInsets encapsulates four different CGFloat values for the inset values of the top, bottom, left, and right individually. Positive inset values shrink the content area, while negative inset values will effectively increase it. Make sure you create the image first and apply the insets there and then, Once that is done then apply the image to the backgroundView as opposed to trying to edit the edge insets from the backgroundView.image property.
UIImageView *cellBGIV =
[[UIImageView alloc] initWithImage:[[UIImage imageNamed:#"imageName"]
resizableImageWithCapInsets:UIEdgeInsetsMake(5.0, 5.0, 5.0, 5.0)]];
cell.backgroundView = cellBGIV;
I draw a border on my UIImageView...
[[albumImage layer] setBorderColor:[[UIColor whiteColor] CGColor]];
[[albumImage layer] setBorderWidth:10.0];
But those extra 10 pixels are drawn inside the image view. Part of my image is cut off! I want to either:
Shrink the UIImage with a 0.96 factor so it fits inside the border.. or
Shrink the UIImageView down 10 pixels on each side in IB, then draw the border outside the image view
Using contentMode, transform, and contentScaleFactor haven't been the correct solution. The last two scale the entire image view (including the border). Content mode just changes how the image fits in the view (which has already been set, in my case)
I would add the image view into a container view and draw the border on the container view. If you're doing the container in XIB then you can set the size there. If you're doing it in code, set the image view frame as:
imageView.frame = CGRectInset(containerView.bounds, 10, 10);
I want to use custom background image for UISegmentedControl like "Find My Friends". Here's how their resizable images look like:
source http://feedzr.com/source.png
source http://feedzr.com/inwork.png
How do I create that complex shadow effect in Core Graphics?
EDIT
The bottom image is just how the above looks like when working with a leather background in a real UISegmentedControl.There're lot's of effects in the resizable image like:
bottom gloss, top inner shadow and partial gradient from top to bottom.
I just can't see how & what effects are being used in this image. I'm not asking how to use UIEdgeInsets.
These are just 2 images. One with the shadow one without…
You have to create these Images with CapInsets to make them resizable
For example
UIImage *buttonImage = [[UIImage imageNamed:#"yourImage"]
resizableImageWithCapInsets:UIEdgeInsetsMake(1, 11, 0, 20)];
To know how UIEdgeInsets work read:
How does UIEdgeInsetsMake work?
Or in the Apple Doc:
UIEdgeInsetsMake
Creates an edge inset for a button or view.
UIEdgeInsets UIEdgeInsetsMake (
CGFloat top,
CGFloat left,
CGFloat bottom,
CGFloat right
);
Parameters
top
The inset at the top of an object.
left
The inset on the left of an object
bottom
The inset on the bottom of an object.
right
The inset on the right of an object.
Return Value
An inset for a button or view
Discussion
An inset is a margin around the drawing rectangle where each side (left, right, top, and bottom) can have a different value.
Availability
Available in iOS 2.0 and later.
See Also
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html