如何在UIButton子类中设置UIButton类型

Har*_*ain 16 subclass uibutton ios

我是UIButton的子类,我想要的是将按钮类型设置为Round Rect.

Button.h

@interface Button : UIButton {}
    - (void)initialize;
@end
Run Code Online (Sandbox Code Playgroud)

Button.m

@implementation Button

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


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

- (void)initialize
{
    self.titleLabel.font = [UIFont systemFontOfSize:20];
    self.titleLabel.textColor = [UIColor redColor];
    self.titleLabel.textAlignment = UITextAlignmentCenter;
   //[UIButton buttonWithType:UIButtonTypeRoundedRect];
}

@end
Run Code Online (Sandbox Code Playgroud)

在这里我尝试[UIButton buttonWithType:UIButtonTypeRoundedRect]但它不起作用.任何人都可以建议如何使其工作?

我在之前的许多文章中都知道,不推荐使用Subclassing UIButton,但事实上在Developer's Docs中没有提及NOT子类化它.

Cal*_*leb 12

您可以在CocoaBuilder的主题如何子类UIButton中找到讨论有用,特别是Jack Nutting建议忽略buttonType:

请注意,这样buttonType没有显式设置为任何东西,这可能意味着它是UIButtonTypeCustom.文档似乎没有实际指定,但由于这是枚举中的0值,这可能发生了什么(这似乎也是可观察的行为)


Con*_*lon 11

不是你想要的,但请记住你的子类仍然有buttonWithType方法,它工作正常.

buttonWithType调用您的子类initWithFrame,并适当地设置类型.

SubclassButton *myButton=[SubclassButton buttonWithType:UIButtonTypeRoundedRect];
Run Code Online (Sandbox Code Playgroud)


Mob*_*Dan 10

UIButton Swift中的子类

*以下代码适用于Swift 3及更高版本.

你不能设置buttonType一个的UIButton设计子类.它会自动设置为custom表示您将简单的外观和行为作为起点.

如果要重用设置按钮外观的代码,则可以在不进行子类化的情况下执行此操作.一种方法是提供创建UIButton和设置视觉属性的工厂方法.

避免子类化的示例工厂方法

extension UIButton {
    static func createStandardButton() -> UIButton {
        let button = UIButton(type: UIButtonType.system)
        button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
        button.setTitleColor(UIColor.black, for: .normal)
        button.setTitleColor(UIColor.gray, for: .highlighted)
        return button
    }
}

let button = UIButton.createStandardButton()
Run Code Online (Sandbox Code Playgroud)

UIButton当其他自定义技术足够时,我避免继承子类.工厂方法示例是一个选项.还有其他选项,包括UIAppearance API等.

有时需要进行子类化的定制需求.例如,我已经创建了UIButton子类来精确控制按钮在响应触摸事件时的动画效果,或者在按下时按钮调用预定义的委托或闭包(而不是#selector为每个实例分配一个).

以下是基本UIButton子类示例作为起点.

示例UIButton子类

internal class CustomButton: UIButton {

    init() {
        // The frame can be set outside of the initializer. Default to zero.
        super.init(frame: CGRect.zero)
        initialize()
    }

    required init?(coder aDecoder: NSCoder) {
        // Called when instantiating from storyboard or nib
        super.init(coder: aDecoder)
        initialize()
    }

    func initialize() {
        print("Execute common initialization code")
    }
}

let button = CustomButton()
print(button.buttonType == .custom)  // true
Run Code Online (Sandbox Code Playgroud)

 

关于 UIButtonType

自2012年提出问题以来,UIButtonType.roundedRect已被弃用.头文件注释说要使用UIButtonType.system.

以下内容来自UIButton.h,在Xcode中转换为Swift

public enum UIButtonType : Int {

    case custom // no button type

    @available(iOS 7.0, *)
    case system // standard system button

    case detailDisclosure
    case infoLight
    case infoDark
    case contactAdd

    public static var roundedRect: UIButtonType { get } // Deprecated, use UIButtonTypeSystem instead
}
Run Code Online (Sandbox Code Playgroud)

  • 并不是说我喜欢故事板,而是工厂方法并不真正适用于故事板。除此之外,这是一个非常好的策略。 (2认同)

小智 6

创建一个方便的 init 对我有用:

class CustomButton: UIButton {
    
    convenience init() {
        self.init(type: .system)
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        /*Do customization here*/
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        
        /*Do customization here*/
    }
}
Run Code Online (Sandbox Code Playgroud)