使用自定义drawRect创建圆形UIButton:方法

时间:2017-03-15 15:41:33

标签: ios objective-c uibutton

我的目标是创建一个自定义UIButton子类,创建一个带有一些附加功能的圆形(或圆形矩形)按钮。

经过一番搜索后,我发现只需设置按钮图层的cornerRadius就可以让按钮成为最简单的方法:

@implementation MyRoundButton

-(id)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame])
        [self setupView];

    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    if(self = [super initWithCoder:aDecoder])
        [self setupView];

    return self;
}

-(void)setupView {    
    self.layer.cornerRadius = MIN(self.frame.size.height, self.frame.size.width) / 2.0;
}

只要我不覆盖drawRect:

,这样就可以了
- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
}

当然我想向drawRect:添加一些自定义绘图代码,但即使只有[super drawRect:rect]按钮不再是圆形:它在其边界内绘制为矩形。

这怎么可能?如何使用简单的超级调用覆盖方法会改变行为?

如何避免此问题?我已经尝试让图层保持不变,只需在drawRect:中手动绘制背景。但是,该按钮无论如何都会绘制其背景矩形,并且我的自定义绘图位于其上方。

那么,如何解决这个问题呢?

2 个答案:

答案 0 :(得分:1)

示例中的图层在概念上包含一个带有圆角半径的背景,但空覆盖drawRect:会导致忽略它。这是因为,通常情况下,UIView的实例取决于其内置图层(CALayer的一个实例)来呈现其内容,因此drawRect:不是{\ n}调用。但是,该图层能够将绘图行为委托给其视图,并且如果您实现drawRect:,则会执行此操作。

如果您只是简单地对UIView进行子类化,则不应该出现任何问题。但是,对UIButton这样的框架组件进行子类化有点过分。一个潜在的问题是对-[super drawRect:]的呼吁;很难确切知道可能导致什么恶作剧,但这可能是问题的根源。默认情况下,UIButton不需要进行任何自定义绘图;它包含一个私有类UIButtonLabel的嵌套实例,用于绘制按钮的标题。

不要试图覆盖内部细节是私有的类的绘制行为,而是考虑使用一个或多个静态图像,只需为一个或多个状态设置按钮的背景图像属性。

答案 1 :(得分:0)

看看这是否有所改变......

-(void)setupView {    
    self.layer.cornerRadius = MIN(self.frame.size.height, self.frame.size.width) / 2.0;
    self.clipsToBounds = YES;
}