xib 高效 tip: 给你的 view 设置任意圆角

实际开发中我们经常需要给 view 设置圆角,如果是给四个角设置相同大小的圆角,使用系统 api 即可。

但有时需要给四个角设置不同大小的圆角,此时系统 api 就不能满足了。为了提高开发效率,我结合 CAShapeLayerUIBezierPath 封装了一个 CornerView

  • 可以通过代码直接设置某个角的圆角:
// 设置左上角圆角
self.cornerView.topLeftCornerRadious = 40;
  • 也支持在 xib 上设置:

Swift 和 Objective-C 的源码如下:

  • Swift:
import UIKit

@IBDesignable

class CornerView: UIView {
    
    /// 左上角圆角
    @IBInspectable var topLeftCornerRadious: CGFloat = 0 {
        didSet {
            refreshCorner()
        }
    }
    /// 右上角圆角
    @IBInspectable var topRightCornerRadious: CGFloat = 0 {
        didSet {
            refreshCorner()
        }
    }
    /// 左下角圆角
    @IBInspectable var bottomLeftCornerRadious: CGFloat = 0 {
        didSet {
            refreshCorner()
        }
    }
    /// 右下角圆角
    @IBInspectable var bottomRightCornerRadious: CGFloat = 0 {
        didSet {
            refreshCorner()
        }
    }
    
    private func refreshCorner() {
        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        self.layer.mask = maskLayer
        
        let borderPath = UIBezierPath()
        // 起点
        borderPath.move(to: .init(x: 0, y: topLeftCornerRadious))
        // 左上角
        borderPath.addQuadCurve(to: .init(x: topLeftCornerRadious, y: 0), controlPoint: .zero)
        // 直线,到右上角
        borderPath.addLine(to: .init(x: bounds.width-topRightCornerRadious, y: 0))
        // 右上角圆角
        borderPath.addQuadCurve(to: .init(x: bounds.width, y: topRightCornerRadious), controlPoint: .init(x: bounds.width, y: 0))
        // 直线,到右下角
        borderPath.addLine(to: .init(x: bounds.width, y: bounds.height-bottomRightCornerRadious))
        // 右下角圆角
        borderPath.addQuadCurve(to: .init(x: bounds.width-bottomRightCornerRadious, y: bounds.height), controlPoint: .init(x: bounds.width, y: bounds.height))
        // 直线,到左下角
        borderPath.addLine(to: .init(x: bottomLeftCornerRadious, y: bounds.height))
        // 左下角圆角
        borderPath.addQuadCurve(to: .init(x: 0, y: bounds.height-bottomLeftCornerRadious), controlPoint: .init(x: 0, y: bounds.height))
        // 回到起点
        borderPath.addLine(to: .init(x: 0, y: topLeftCornerRadious))
        
        maskLayer.path = borderPath.cgPath
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        refreshCorner()
    }
    
}
  • Objective-C:
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface CQCornerView : UIView

/// 左上角圆角
@property (nonatomic, assign) IBInspectable CGFloat topLeftCornerRadious;
/// 右上角圆角
@property (nonatomic, assign) IBInspectable CGFloat topRightCornerRadious;
/// 左下角圆角
@property (nonatomic, assign) IBInspectable CGFloat bottomLeftCornerRadious;
/// 右下角圆角
@property (nonatomic, assign) IBInspectable CGFloat bottomRightCornerRadious;

@end

NS_ASSUME_NONNULL_END





#import "CQCornerView.h"

IB_DESIGNABLE

@implementation CQCornerView

- (void)setTopLeftCornerRadious:(CGFloat)topLeftCornerRadious {
    _topLeftCornerRadious = topLeftCornerRadious;
    [self refreshCorner];
}

- (void)setTopRightCornerRadious:(CGFloat)topRightCornerRadious {
    _topRightCornerRadious = topRightCornerRadious;
    [self refreshCorner];
}

- (void)setBottomLeftCornerRadious:(CGFloat)bottomLeftCornerRadious {
    _bottomLeftCornerRadious = bottomLeftCornerRadious;
    [self refreshCorner];
}

- (void)setBottomRightCornerRadious:(CGFloat)bottomRightCornerRadious {
    _bottomRightCornerRadious = bottomRightCornerRadious;
    [self refreshCorner];
}

- (void)refreshCorner {
    CAShapeLayer *maskLayer = [CAShapeLayer new];
    maskLayer.frame = self.bounds;
    self.layer.mask = maskLayer;
    
    UIBezierPath *borderPath = [UIBezierPath new];
    
    CGFloat width = self.bounds.size.width;
    CGFloat height = self.bounds.size.height;
    
    // 起点
    [borderPath moveToPoint:CGPointMake(0, _topLeftCornerRadious)];
    // 弧线,到左上角上方
    [borderPath addQuadCurveToPoint:CGPointMake(_topLeftCornerRadious, 0) controlPoint:CGPointZero];
    // 直线,到右上角
    [borderPath addLineToPoint:CGPointMake(width - _topRightCornerRadious, 0)];
    // 右上角圆角
    [borderPath addQuadCurveToPoint:CGPointMake(width, _topRightCornerRadious) controlPoint:CGPointMake(width, 0)];
    // 直线,到右下角
    [borderPath addLineToPoint:CGPointMake(width, height - _bottomRightCornerRadious)];
    // 右下角圆角
    [borderPath addQuadCurveToPoint:CGPointMake(width - _bottomRightCornerRadious, height) controlPoint:CGPointMake(width, height)];
    // 直线,到左下角
    [borderPath addLineToPoint:CGPointMake(_bottomLeftCornerRadious, height)];
    // 左下角圆角
    [borderPath addQuadCurveToPoint:CGPointMake(0, height - _bottomLeftCornerRadious) controlPoint:CGPointMake(0, height)];
    // 回到起点
    [borderPath addLineToPoint:CGPointMake(0, _topLeftCornerRadious)];
    
    maskLayer.path = borderPath.CGPath;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    [self refreshCorner];
}

@end
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祖安狂人学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值