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

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

问题描述:

我的目标是创建一个自定义UIButton子类,该子类创建带有一些附加功能的圆形(或圆形矩形)按钮。使用自定义drawRect创建圆形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:手动绘制背景。然而,该按钮仍然绘制其背景矩形,并且我的自定义绘图位于其上。

那么,该如何解决?

+0

“如何重写一个简单的超级调用的方法改变行为”的UIButton可以检查是否有越权和行为方式不同。它根本不需要使用drawRect来实现。 –

+0

这可能是一个解释,但是这种实现的原因是什么?没有改变的代码会改变某些东西很奇怪...但是:实际的问题是别的:如何创建一个使用'drawRect的圆形按钮:' –

+0

为什么你想调用'[super drawRect:rect];'? – DonMag

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

如果你只是继承UIView,这应该不会有任何问题。但是,子类化框架组件(如UIButton)稍微有些不便。一个潜在的问题是致电-[super drawRect:];很难确切知道可能造成的恶作剧,但这可能是问题的根源。默认情况下,UIButton不需要执行任何自定义绘图;它包含一个私有类的嵌套实例,即UIButtonLabel,它绘制该按钮的标题。

不要试图覆盖内部细节为私人的类的绘图行为,请考虑使用一个或多个静态图像并简单地设置一个或多个状态的按钮的背景图像属性。

+0

非常感谢,这听起来很合理。但是我不确定这是否完全正确:我会理解,如果实现'drawRect:'将用作触发器以从图层绘制切换到视图绘制,并且因此图层将被简单地忽略。但这种情况并非如此。如果执行'drawRect:',图层将始终保持其背景,并且我无法阻止它执行此操作。因此,图层绘制仍处于活动状态,我只能添加视图绘制,但我的目标是**替换图层绘制。我怎样才能做到这一点? –

+0

我编辑了我的答案。你有没有尝试消除对' - [super drawRect:]'的调用? – jlehr

+0

'super'调用仅用于演示,即使是不改变任何内容的“drawRect:”的重写版本也会导致问题。去除'supper'调用不会改变任何东西。 我现在明白了,即使添加一个覆盖版本也足以改变一些东西。然而Ithe的主要目标是相同的:如何覆盖UIButton,使其四舍五入并同时使用自定义绘图?只有自定义绘图不起作用,因为我无法防止按钮背景层被遮挡。设置图层'cornerRadius'不起作用,因为我无法再使用自定义绘图 –

看是否有此改变任何东西......

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

这部分解决了问题:即使我使用自定义绘图(覆盖'drawRect:'),现在按钮被裁剪掉了到其界限(惊喜,惊喜:),因此一个**阴影**,这是添加到图层不再可见... –

+0

对不起,没有看到任何关于需要阴影的问题。有不止一种方法来做事情......也许如果你发布你最终的目标是什么? – DonMag