Create a rectangle with just two rounded corners in swift?

后端 未结 15 2939
南笙
南笙 2020-11-28 03:14

I need to create a rectangle that have just two rounded corners in swift (Objective C code also ok).

At the moment my code is creating two rectangles with



        
相关标签:
15条回答
  • 2020-11-28 03:43

    Objective-C version of iWasRobbed's answer:

    UIView+RoundCorners.h

    #import <UIKit/UIKit.h>
    
    @interface UIView (RoundCorners)
    
    /**
     Rounds the given set of corners to the specified radius
    
     - parameter corners: Corners to round
     - parameter radius:  Radius to round to
     */
    - (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius;
    
    /**
     Rounds the given set of corners to the specified radius with a border
    
     - parameter corners:     Corners to round
     - parameter radius:      Radius to round to
     - parameter borderColor: The border color
     - parameter borderWidth: The border width
     */
    - (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
    
    /**
     Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
    
     - parameter diameter:    The view's diameter
     - parameter borderColor: The border color
     - parameter borderWidth: The border width
     */
    - (void)fullyRoundWithDiameter:(CGFloat)diameter borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
    
    @end
    

    UIView+RoundCorners.m

    #import "UIView+RoundCorners.h"
    
    @implementation UIView (RoundCorners)
    
    - (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius {
        [self _roundCorners:corners radius:radius];
    }
    
    - (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
        CAShapeLayer *mask = [self _roundCorners:corners radius:radius];
        [self addBorderWithMask:mask borderColor:borderColor borderWidth:borderWidth];
    }
    
    - (void)fullyRoundWithDiameter:(CGFloat)diameter borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
        self.layer.masksToBounds = YES;
        self.layer.cornerRadius = diameter / 2;
        self.layer.borderWidth = borderWidth;
        self.layer.borderColor = borderColor.CGColor;
    }
    
    - (CAShapeLayer *)_roundCorners:(UIRectCorner)corners radius:(CGFloat)radius {
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
        CAShapeLayer *mask = [CAShapeLayer layer];
        mask.path = path.CGPath;
        self.layer.mask = mask;
        return mask;
    }
    
    - (void)addBorderWithMask:(CAShapeLayer *)mask borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
        CAShapeLayer *borderLayer = [CAShapeLayer layer];
        borderLayer.path = mask.path;
        borderLayer.fillColor = UIColor.clearColor.CGColor;
        borderLayer.strokeColor = borderColor.CGColor;
        borderLayer.lineWidth = borderWidth;
        borderLayer.frame = self.bounds;
        [self.layer addSublayer:borderLayer];
    }
    
    @end
    
    0 讨论(0)
  • 2020-11-28 03:48

    One simple hack could be as following. Take views like below example in image. Red View will have rounded corners and Yellow View (inside Red View) will prevent the corners to be rounded

    Now write below code for Red View.

            self.myView.layer.cornerRadius = 15
    

    Make sure you don't write any code as clipsToBounds = true or masksToBounds = true.

    Below image is the result

    Placement of Yellow View will decide, which 2 corners will not be rounded. Hope this is easy to implement.

    0 讨论(0)
  • 2020-11-28 03:48
    view.layer.cornerRadius = 10.0
    view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMaxYCorner, .layerMinXMaxYCorner]
    

    Best way to do it!

    0 讨论(0)
  • 2020-11-28 03:51

    Swift 4:

    let maskPath = UIBezierPath(
                roundedRect: view.bounds,
                byRoundingCorners: [.allCorners],
                cornerRadii: CGSize(width: 10.0, height: 10.0)
            )
    
    let shape = CAShapeLayer()
    shape.path = maskPath.cgPath
    
    view.layer.mask = shape
    
    0 讨论(0)
  • 2020-11-28 03:54

    Update: See this answer below for Swift 4 / iOS 11 which is much, much easier


    Here's a quick Swift 3 extension you can use to do rounding and optional borders.

    Note: if you're using autolayout, you may need to call this in one of the view lifecycle callbacks like viewDidLayoutSubviews or layoutSubviews after the view has been constrained.

    import UIKit
    
    extension UIView {
        
        /**
         Rounds the given set of corners to the specified radius
         
         - parameter corners: Corners to round
         - parameter radius:  Radius to round to
         */
        func round(corners: UIRectCorner, radius: CGFloat) {
            _ = _round(corners: corners, radius: radius)
        }
        
        /**
         Rounds the given set of corners to the specified radius with a border
         
         - parameter corners:     Corners to round
         - parameter radius:      Radius to round to
         - parameter borderColor: The border color
         - parameter borderWidth: The border width
         */
        func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
            let mask = _round(corners: corners, radius: radius)
            addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
        }
        
        /**
         Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
         
         - parameter diameter:    The view's diameter
         - parameter borderColor: The border color
         - parameter borderWidth: The border width
         */
        func fullyRound(diameter: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
            layer.masksToBounds = true
            layer.cornerRadius = diameter / 2
            layer.borderWidth = borderWidth
            layer.borderColor = borderColor.cgColor;
        }
        
    }
    
    private extension UIView {
        
        @discardableResult 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
        }
        
        func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) {
            let borderLayer = CAShapeLayer()
            borderLayer.path = mask.path
            borderLayer.fillColor = UIColor.clear.cgColor
            borderLayer.strokeColor = borderColor.cgColor
            borderLayer.lineWidth = borderWidth
            borderLayer.frame = bounds
            layer.addSublayer(borderLayer)
        }
        
    }
    
    0 讨论(0)
  • 2020-11-28 03:58

    Updated iWasRobbed's answer to work with the Swift 3.0 GM version:

    import UIKit
    
    extension UIView {
    
        /**
         Rounds the given set of corners to the specified radius
    
         - parameter corners: Corners to round
         - parameter radius:  Radius to round to
         */
        func round(corners: UIRectCorner, radius: CGFloat) {
            _round(corners: corners, radius: radius)
        }
    
        /**
         Rounds the given set of corners to the specified radius with a border
    
         - parameter corners:     Corners to round
         - parameter radius:      Radius to round to
         - parameter borderColor: The border color
         - parameter borderWidth: The border width
         */
        func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
            let mask = _round(corners: corners, radius: radius)
            addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
        }
    
        /**
         Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
    
         - parameter diameter:    The view's diameter
         - parameter borderColor: The border color
         - parameter borderWidth: The border width
         */
        func fullyRound(diameter: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
            layer.masksToBounds = true
            layer.cornerRadius = diameter / 2
            layer.borderWidth = borderWidth
            layer.borderColor = borderColor.cgColor;
        }
    
    }
    
    private extension UIView {
    
        @discardableResult 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
        }
    
        func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) {
            let borderLayer = CAShapeLayer()
            borderLayer.path = mask.path
            borderLayer.fillColor = UIColor.clear.cgColor
            borderLayer.strokeColor = borderColor.cgColor
            borderLayer.lineWidth = borderWidth
            borderLayer.frame = bounds
            layer.addSublayer(borderLayer)
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题