Complete the upper right and left corners of the gaze?

I am trying to figure out how to mask a UIView to display a shape representing a square and a half circle sitting on it.

Basically, it will be similar to applying the border radius for only the top two corners to round them and create an arc.

I use fast and it drives me crazy.

EDIT: CornerRadius is not doing what I want. I feel like I have to use CGShapeLayer, but I'm not sure how to create an arc.

EDIT2: enter image description here

EDIT3:

Given the explanation of what I want, providing pictures and explaining that I don’t understand what I need to do, or how I need it, is not enough for some people, this is what I tried:

Trying to set the layer.cornerRadius property and then bring the bottom of the view off the screen to hide the lower corners from cropping, this type of masking was too circular and did not provide the correct arc results.

I tried using UIBezierPath by setting the top two corners to use cornerRadii from width / 2 views. It also did not produce proper results. Trying to assign hardcode values ​​to cornerRadii, I noticed that regardless of the value, I could not get the results that I wanted.

What other options are there? Or am I just using BezierPath incorrectly?

EDIT 4:

Here is my original code.

 override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) let bezierPath = UIBezierPath(roundedRect: navBarView.bounds, byRoundingCorners: [.TopLeft, .TopRight], cornerRadii: CGSizeMake(navBarView.bounds.width / 2, navBarView.bounds.width / 2)).CGPath; let shapeLayer = CAShapeLayer(); shapeLayer.bounds = navBarView.bounds shapeLayer.path = bezierPath navBarView.layer.mask = shapeLayer updateUI() // <-- Label text, etc. } 

Also, as mentioned earlier, an attempt to make navBarView.layer.cornerRadius = x

-2
source share
4 answers

Try the following:

 let path = UIBezierPath(roundedRect:self.view.bounds, byRoundingCorners:[.TopLeft, .TopRight], cornerRadii: CGSizeMake(20, 20)) let maskLayer = CAShapeLayer() maskLayer.frame = self.view.bounds; maskLayer.path = path.CGPath self.view.layer.mask = maskLayer; 

The UIBezierPath class allows UIBezierPath to define a path consisting of straight and curved line segments and display this path in user views.

  • Creating rounded corners of a path in UIBezierPath
  • To generate a CAShapeLayer, it is installed in one of the paths
  • the view you want on the one hand, only rounded corners 2 as a mask layer

Example:

 let DynamicView=UIView(frame: CGRectMake(50, 200, 200, 300)) DynamicView.backgroundColor=UIColor.redColor() let path = UIBezierPath(roundedRect:DynamicView.bounds, byRoundingCorners:[.TopLeft, .TopRight], cornerRadii: CGSizeMake(20, 20)) let maskLayer = CAShapeLayer() maskLayer.frame = DynamicView.bounds; maskLayer.path = path.CGPath DynamicView.layer.mask = maskLayer; self.view.addSubview(DynamicView) 

Result:

Blockquote

+5
source

Not so difficult, you need to add a mask to the presentation layer. Note that adding a mask cuts out everything from the mask itself.
Another thing you should pay attention to is that if your view is resized, you should also be adapted to the mask, since it does not automatically update the path.
By imagining that you are using SWIFT, you can subclass UIView:


 override func layoutSubviews() { super.layoutSubviews() maskLayer.frame = layer.bounds maskLayer.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: [.TopLeft, .TopRight], cornerRadii: CGSizeMake(bounds.size.widht/2, bounds.size.widht/2)).CGPath } override init(frame: CGRect) { super.init(frame: frame) layer.mask = maskLayer } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) layer.mask = maskLayer } 

maskLayer is a CAShapeLayer that you must create as a constant or as a lazy property. Code not verified.

+1
source

Hi, I had the same problem. I'm rounded corners after the view has changed by sending a queue

  self.lblShortDescription.frame = CGRectMake(self.lblShortDescription.frame.origin.x, self.lblShortDescription.frame.origin.y, width, self.lblShortDescription.requiredHeight()) // here required height is the function to resize the label according to the content. dispatch_async(dispatch_get_main_queue(), { self.viewTopTitaleBack.round([UIRectCorner.TopLeft, UIRectCorner.TopRight], radius: 8.0) // here rounding is again a function I used for rounding the view by passing the parameters. }); extension UILabel{ func requiredHeight() -> CGFloat{ let label:UILabel = UILabel(frame: CGRectMake(0, 0, self.frame.width, CGFloat.max)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.ByWordWrapping label.font = self.font label.text = self.text label.sizeToFit() return label.frame.height } } extension UIView { func round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer { let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) let mask = CAShapeLayer() mask.path = path.CGPath self.layer.mask = mask return mask } } 

Hope this helps.

+1
source

Tested and tried by Ramesh_T to respond , it works great with the addition of .clipsToBounds done right. Works like a charm, especially if it is embedded in an extension function, for example:

( SWIFT 3 )

 extension UIView { func roundCorners(_ corner: UIRectCorner,_ radii: CGFloat) { let maskLayer = CAShapeLayer() maskLayer.frame = self.layer.bounds maskLayer.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corner, cornerRadii: CGSize(width: radii, height: radii)).cgPath self.layer.mask = maskLayer layer.masksToBounds = true } } 

Called in such a way as to round certain views at the top left and right:

 someView.roundCorners([.topRight,.topLeft], 60) 

EDIT

However, looking at the method declaration for UIBezierPath (roundedRect ..): it seems that the angular radii are increased to half the height or width of the view, whichever is less ...

+1
source

Source: https://habr.com/ru/post/1241225/


All Articles