Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rounded Corners only on Top of a UIView

Hi i am searching a clean solution without overwriting drawRect or stuff like that to create a UIView with Rounded corners on the Top of the View. My main problem here is to create variable solution if the view is getting resized or something like that. Is there a clean solution? Apple is this doing too on the first table item. it can't be so hard to do this.

like image 515
mariusLAN Avatar asked Apr 25 '12 13:04

mariusLAN


People also ask

How do you round UIView corners?

If you start with a regular UIView it has square corners. You can give it round corners by changing the cornerRadius property of the view's layer . and smaller values give less rounded corners. Both clipsToBounds and masksToBounds are equivalent.

How do I add inner shadow to UIView with rounded corners?

Add subview with the same color which will be centered on the parent and will be with several pixels smaller. Like this you will have space from each side of the parent. On the parent turn on clipping subviews and add shadow to the inner view. Like this, you can have an inner shadow.


2 Answers

You can do this by setting a mask on your view's layer:

CAShapeLayer * maskLayer = [CAShapeLayer layer]; maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: self.bounds byRoundingCorners: UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii: (CGSize){10.0, 10.}].CGPath;  self.layer.mask = maskLayer; 

IMPORTANT: You should do this in your view's layoutSubviews() method, so the view has already been resized from the storyboard


In Swift <= 1.2

let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: .TopLeft | .TopRight, cornerRadii: CGSize(width: 10.0, height: 10.0)).CGPath  layer.mask = maskLayer 

Swift 2.x

let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: UIRectCorner.TopLeft.union(.TopRight), cornerRadii: CGSizeMake(10, 10)).CGPath layer.mask = maskLayer 

Swift 3.x

let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 10, height: 10)).cgPath layer.mask = maskLayer 
like image 113
Ashley Mills Avatar answered Sep 19 '22 11:09

Ashley Mills


Just tried with Swift 3.0 , Xcode 8.0:

REMEMBER to set your button in viewDidLayoutSubviews() or layoutSubViews as @rob described here .

And when you wanna change your button background, you just need to call:

yourButton.backgroundColor = UIColor.someColour 

Source:

override func viewDidLayoutSubviews() {     super.viewDidLayoutSubviews()      yourButton.layer.masksToBounds = true     yourButton.roundCorners(corners: [.topLeft,.topRight], radius: 5) }  extension UIButton {     func roundCorners(corners:UIRectCorner, radius: CGFloat)     {         let maskLayer = CAShapeLayer()         maskLayer.path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)).cgPath         self.layer.mask = maskLayer     } } 
  • Here is the result:

Default state:

enter image description here

Seleted state:

enter image description here

Hope this help!!

like image 43
Nhat Dinh Avatar answered Sep 22 '22 11:09

Nhat Dinh