Закруглить верхние углы UIView и добавить границу

У меня есть следующий код в категории, которая делает скругление углов. Я также хотел бы нарисовать границу. Но граница не показана на закругленной части угла.

Вот код

- (void) roundTopCorners:(CGFloat) radius
{
    self.layer.masksToBounds = YES;

    CGRect bounds = self.bounds;
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(radius, radius)];

    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = bounds;
    maskLayer.path = maskPath.CGPath;
    maskLayer.strokeColor = [UIColor redColor].CGColor;

    self.layer.mask = maskLayer;
}

3 ответа

Решение

Слой маски не рисуется, просто используется для вычисления маски. Пытаться:

-(void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius
{
    CGRect bounds = self.bounds;
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds
                                                   byRoundingCorners:corners
                                                         cornerRadii:CGSizeMake(radius, radius)];

    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = bounds;
    maskLayer.path = maskPath.CGPath;

    self.layer.mask = maskLayer;

    CAShapeLayer*   frameLayer = [CAShapeLayer layer];
    frameLayer.frame = bounds;
    frameLayer.path = maskPath.CGPath;
    frameLayer.strokeColor = [UIColor redColor].CGColor;
    frameLayer.fillColor = nil;

    [self.layer addSublayer:frameLayer];
}

-(void)roundTopCornersRadius:(CGFloat)radius
{
    [self roundCorners:(UIRectCornerTopLeft|UIRectCornerTopRight) radius:radius];
}

-(void)roundBottomCornersRadius:(CGFloat)radius
{
    [self roundCorners:(UIRectCornerBottomLeft|UIRectCornerBottomRight) radius:radius];
}

Рамка, которую вы сейчас видите нарисованной, является обычной рамкой UITextField, поэтому установите для стиля рамки значение none. Вы также должны будете отрегулировать вставки, чтобы компенсировать тот факт, что со стилем рамки, установленным на none, обычно нет вставки.

Быстрая версия ответа Дэвида Берри:

func roundCorners(corners:UIRectCorner, radius:CGFloat) {
    let bounds = self.bounds

    let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSizeMake(radius, radius))

    let maskLayer = CAShapeLayer()
    maskLayer.frame = bounds
    maskLayer.path = maskPath.CGPath

    self.layer.mask = maskLayer

    let frameLayer = CAShapeLayer()
    frameLayer.frame = bounds
    frameLayer.path = maskPath.CGPath
    frameLayer.strokeColor = UIColor.redColor().CGColor
    frameLayer.fillColor = nil

    self.layer.addSublayer(frameLayer)
}

func roundTopCornersRadius(radius:CGFloat) {
    self.roundCorners([UIRectCorner.TopLeft, UIRectCorner.TopRight], radius:radius)
}

func roundBottomCornersRadius(radius:CGFloat) {
    self.roundCorners([UIRectCorner.BottomLeft, UIRectCorner.BottomRight], radius:radius)
}

Это, вероятно, очень поздний ответ, но я бы хотел поделиться предложенным решением, основываясь на ответах разных людей из разных похожих вопросов. Я получил большую помощь от ответа Войтеха выше.

extension UIView {
    func EZRoundCorners(corners:UIRectCorner, radius: CGFloat) -> CAShapeLayer {
        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.CGPath
        self.layer.mask = mask
        return mask
    }

    func EZRoundCornersWithBorder(corners:UIRectCorner, radius:CGFloat, color:UIColor, width:CGFloat) -> CAShapeLayer {

        let mask = self.EZRoundCorners(corners, radius: radius)

        // Add border
        let borderLayer = EZCALayer()
        borderLayer.path = mask.path // Reuse the Bezier path
        borderLayer.fillColor = UIColor.clearColor().CGColor
        borderLayer.strokeColor = color.CGColor
        borderLayer.lineWidth = width
        borderLayer.frame = self.bounds
        self.layer.addSublayer(borderLayer)
        return borderLayer
    }

    func removeEZLayers () {
        for layer in self.layer.sublayers! {
            if layer is EZCALayer {
                layer.removeFromSuperlayer()
            }
        }
    }
}

class EZCALayer : CAShapeLayer {
}

Я унаследовал от CAShapeLayer, поэтому я могу удалить подслои границ, если я больше не хочу их использовать.

      label.layer.cornerRadius = 3.0 
     label.layer.maskedCorners = [.layerMinXMinYCorner,.layerMinXMaxYCorner]//round top left and bottom left corners

Источник: https://www.hackingwithswift.com/example-code/calayer/how-to-round-only-specific-corners-using-maskedcorners

Изображение рабочего раствора

Другие вопросы по тегам