子类化视图时如何减少代码冗余?

时间:2015-01-24 17:44:41

标签: ios objective-c uiview uibutton

我有一个要求,我需要改变UIB组件,如UIButton,UIView和UITextField。我需要做的只是将边框的半径更改为圆形而不是默认的尖锐矩形。

我这样做的方法是将 UIView子类化为UIViewRoundCorner ,将 UIButton子类化为UIButtonRoundCorner ,将 UITextField子类化为UITextFieldRoundCorner ,并在每个子类中包含用以下方法覆盖drawRect方法:

- (void)drawRect:(CGRect)rect {
    // Drawing code
    CALayer *layer = [self layer];
    [layer setMasksToBounds:YES];
    [layer setCornerRadius:3.0f];
    [layer setBorderWidth:1.0f];
}

代码是冗余的,我试图弄清楚如何删除这种冗余。由于所有这些元素都是从UIView继承而来的,有可能以某种方式将UIView子类化并在所有其他视图中实现吗?

2 个答案:

答案 0 :(得分:2)

您根本不需要进行子类化来完成此操作。 Objective-C有一个很棒的功能,允许您向现有类添加行为:categories

您可以在UIView上的某个类别中添加方法(让我们称之为RoundedCorners):

@implementation UIView (RoundedCorners)

- (void)ps_addRoundedCorners;

@end

@implementation UIView (RoundedCorners)

- (void)ps_addRoundedCorners {
    CALayer *layer = [self layer];
    [layer setMasksToBounds:YES];
    [layer setCornerRadius:3.0f];
    [layer setBorderWidth:1.0f]; 
}

@end

并将它与任何UIView子类一起使用:

UIButton *button = ...  //create a button somehow
[button ps_addRoundedCorners];

方法名称中的ps_前缀用于避免名称冲突(如果其他人在私有框架中添加了具有相同名称的方法)。

答案 1 :(得分:1)

protocol RoundedCorner {
    func makeCornerRadius(radius:CGFloat)
}

extension RoundedCorner where Self:UIView{
    func makeCornerRadius(radius:CGFloat){
        self.layer.cornerRadius = radius
    }
}

class CustomButton: UIButton, RoundedCorner {

    override func drawRect(rect: CGRect) {
        super.drawRect(rect)
        self.makeCornerRadius(5)
    }
}

您可以创建协议并扩展该协议以进行默认实施。然后对于您想要角半径的每个自定义视图,只需实现该协议。这样,您可以最大限度地减少代码冗余。