IOS Swift card effect image is getting clipped - ios

Following is my code to create CardView and add shadow effect
override func awakeFromNib() {
super.awakeFromNib()
self.layoutIfNeeded()
cellBgview.layer.cornerRadius = 15.0
cellBgview.layer.borderWidth = 1.0
cellBgview.layer.borderColor = UIColor.clear.cgColor
cellBgview.layer.shadowColor = UIColor.gray.cgColor
cellBgview.layer.shadowRadius = 14.0
cellBgview.layer.shadowOpacity = 0.5
cellBgview.layer.shadowPath = UIBezierPath(roundedRect: cellBgview.bounds, cornerRadius: cellBgview.layer.cornerRadius).cgPath
// In
}
This looks like this
Corner radius not working in this case to make corner radius work I have added following code
cellBgview.clipsToBounds = true
After adding above code it looks this
Note that after adding cellBgview.clipsToBounds = true card elevation and shadow is missing but corner radius appears
How to make card view with corner radius and shadow without image getting clip.
Also tried
cellBgview.layer.masksToBounds = true
but it is not working.

Add another UIView in your cell and add imageView in that UIView...Apply corner radius to imageView. Apply shadow to that UIView holding imageView. add clipsToBounds to imageView not to that UIView because clipsToBounds clip anything outside bounds that can be shadow as well. will solve your issue

add a uiview in your cell, lets call it content view. in this view add another uiview in which you'll add the image view and your bottom labels. So actual hierarchy would look like this
--Cell
---UIView //add shadow on this view, also make its backgroundColor to clear color
---UIView //add corner radius to this view and clipsToBounds = true for this view
---UIImageView
---Bottom Labels / Another UIView / Stack View
this hierarchy will help you to achieve the image round corner only on top and view round corners on bottom content

Try this to achieve Shadow, Corner Radius, Border in one view.
cellBgview.backgroundColor = UIColor.white
let cellBgViewLayer = cellBgview.layer()
cellBgViewLayer?.masksToBounds = false
cellBgViewLayer?.shadowColor = UIColor.lightGray.cgColor
cellBgViewLayer?.shadowOpacity = 1.0
cellBgViewLayer?.shadowRadius = 6.0
cellBgViewLayer?.shadowOffset = CGSize(width: 0, height: 0)
cellBgViewLayer?.shouldRasterize = true
cellBgViewLayer?.cornerRadius = 5.0
cellBgViewLayer?.borderColor = UIColor.lightGray.cgColor
cellBgViewLayer?.borderWidth = 1.0
cellBgViewLayer?.shadowPath = UIBezierPath(rect: cellBgview.bounds).cgPath

Related

SWIFT - Setting layer.cornerRadius greater than the view height causes issues

I actually want to add a corner radius to a view on only one side. The radius is supposed to be of full height. This is my implementation.
someView.layer.cornerRadius = someView.frame.size.height
someView.layer.maskedCorners = [.layerMaxXMaxYCorner]
This does the job as required, but it adds extra shapes on other sides as shown below.
What might be the problem?
This looks like an iOS bug, I was able to reproduce it
But usually you don't wanna set cornerRadius greater than half view minimum side, in your case:
someView.layer.cornerRadius = someView.frame.size.height / 2
I assume it'll produce result you're expecting:
Corner radius is radius of a circle inscribed in the corner of a rectangle, I think that's why there may be problems with radius bigger than side/2: circle doesn't fit a rectangle anymore
i had the same problem. I needed to make the height of the view 16 and the bottom corners radius also 16.
My solution:
add the view you want to round to the bottom view
clip the bottomView to specific size (in my case width = window width and height=16)
make height of the rounded view = cornerRadius * 2 (in my case 32)
pin rounded view to superView, excluding the opposite edge which you want to round off (in my case i wanted to round bottom edge roundedView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .top))
code
private let bottomView: UIView = {
let view = UIView(forAutoLayout: ())
view.clipsToBounds = true
return view
}()
private let roundedView: UIView = {
let view = UIView(forAutoLayout: ())
view.clipsToBounds = true
view.contentMode = .scaleAspectFill
view.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
return view
}()
...
contentView.addSubview(bottomView)
bottomView.addSubview(roundedView)
...
func setupConstraints() {
if roundedView.layer.cornerRadius >= roundedView.frame.height / 2 {
roundedView.autoSetDimension(.height, toSize: roundedView.layer.cornerRadius * 2)
} else {
roundedView.autoPinEdge(toSuperviewEdge: .top)
}
roundedView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .top)
bottomView.autoPinEdgesToSuperviewEdges()
}
result:
enter image description here

In iOS, how to have view with rounded corners and drop shadow mask its subview?

I'm trying to create something like this image except for those purple corners. Notice how the blue (shown as purple) contentView is not being clipped or masked by its parent containerView.
The requirements are to have a view which:
Has rounded corners.
Has a shadow.
It's subviews don't leak outside of it or its corners.
Here is the code I'm playing around with and I'm not sure exactly how to get this to work.
let containerView = UIView(frame: CGRect(x: 300, y: 100, width: 200, height: 200))
containerView.backgroundColor = .green
containerView.layer.cornerRadius = 40
containerView.layer.shadowRadius = 50
containerView.layer.shadowOffset = .zero
containerView.layer.shadowColor = UIColor.red.cgColor
containerView.layer.shadowOpacity = 1
view.addSubview(containerView)
let backgroundLayer = CALayer()
backgroundLayer.frame = containerView.layer.bounds
backgroundLayer.backgroundColor = UIColor.black.cgColor
backgroundLayer.opacity = 0.5
backgroundLayer.cornerRadius = containerView.layer.cornerRadius
backgroundLayer.masksToBounds = true
containerView.layer.addSublayer(backgroundLayer)
let contentView = UIView(frame: containerView.bounds)
contentView.backgroundColor = .blue
contentView.alpha = 0.3
// Omitting this line will produce a green square with rounded corners
// and a red shadow.
containerView.addSubview(contentView)
Based on this example code, one of my more specific questions is why doesn't the backgroundLayer which sets masksToBounds = true, mask the view's subview?
Based on this example code, one of my more specific questions is why doesn't the backgroundLayer which sets masksToBounds = true, mask the view's subview?
Because the subview is the subview of the view, not of the backgroundLayer.
Views are layers. Clipping is masking. A layer masks its own drawing and that of its sublayers. The subview's layer is not a sublayer of the backgroundLayer. It is its sibling, not its child. Your view/layer hierarchy looks like this:
containerView
| \
[layer] backgroundLayer
| (clips itself and its sublayers,
contentView but it has no sublayers)
|
[layer]

tableView Scroll then progressView corner radius change automatically

i add progress view in table view .i scroll the uitableView then track corner radius does not show how can i set his corner radius.
even i added the layer corner radius also
progressBar.layer.sublayers![1].cornerRadius = 8
progressBar.subviews[1].clipsToBounds = true
Please use below swift 5.0 extension to set the corner radius
extension UIView{
func setCorner(withRadius:Int, borderWidth:Int = 0, color: UIColor = .clear){
self.layer.cornerRadius = radius
self.layer.borderColor = color
self.layer.borderWidth = borderWidth
self.clipsToBounds = true
}
}
and use it as
progressBar.setCorner(withRadius: 8)//what ever radius you want to set.

How can i drop shadow to top and bottom of view which is inside the table view cell?

I have a view inside the table view cell and I want to show shadow to that view if below situations
if view on first cell then drop shadow to top, left, right.
if view on last cell then drop shadow to bottm, left, right.
other wise drop shadow only on left and right.
Thank You.
yourView.layer.shadowColor = UIColor.black.cgColor
yourView.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
yourView.layer.shadowOpacity = 0.5
yourView.layer.shadowRadius = 2.0
And adapt the code below to the way you want for the corners that you'd like to drop shadow.
var shadowRect: CGRect = yourView.bounds.insetBy(dx: 0, dy: 4) // inset top and bottom of the cell
yourView.layer.shadowPath = UIBezierPath(rect: shadowRect).cgPath
put this code in your class
extension UIView {
func dropShadow(scale: Bool = true) {
layer.masksToBounds = false
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.2
layer.shadowOffset = CGSize.zero
layer.shadowRadius = 5
}}
Then call it:--
YourView.dropShadow(scale: true)

drop shadow around border of UITextView to give it 3d effect in iOS/swift

Is there a way to drop a shadow around the border of a UITextView to give it a 3D effect? The textView has rounded corners.
I don't want to drop a shadow for the content of the textView (i.e. text). Just around the textView border only.
I need to clipToBounds on the textView for the rounded corners.
So far this is what I have tried:
let shadowLayer = CAShapeLayer()
shadowLayer.path = UIBezierPath(roundedRect: textView.bounds, cornerRadius: 15).cgPath
shadowLayer.fillColor = UIColor.clear.cgColor
shadowLayer.shadowColor = UIColor.black.cgColor
shadowLayer.shadowPath = shadowLayer.path
shadowLayer.shadowOffset = CGSize(width: 2, height: 2)
shadowLayer.shadowOpacity = 1
shadowLayer.shadowRadius = 2
textView.layer.addSublayer(shadowLayer)
This results in:
Reason : Clips to bounds = true and shadow on the same view doest not work simultaneous. So to sort out this you have to do follow.
Add your TextView in a UIView (says viewTextBG).
TextView Constraints : top bottom, leading, trailing = 0 wrt. viewTextBG.
Give corner radius to textview and viewTextBG
textview.cornerRadius = 10
viewTextBG.cornerRadius = 10
Give clipsToBounds to textview and viewTextBG
textview.clipsToBounds = True
viewTextBG.clipsToBounds = false
Now give shadow to viewTextBG.
Now everything works, thats all.

Resources