如何创建可重用按钮

mkc*_*842 1 xcode subclass object button

我是Xcode和Objective c的新手.我想创建一个具有特定外观的按钮(可能是导航栏的UIBarButtonItem),我将在不同的视图中重复使用.我已经仔细搜索但无法弄清楚如何.

是否适合子类UIBarButtonItem?我试图这样做,但我很快就在脑海中.一旦我创建了.h和.m文件作为UIBarButtonItem的子类,那么我是否必须实例化一个UIBarButtonItem?那些文件不会自动为我创建一个按钮对象(从父类导入),我可以将其称为self?在它自己的子类中实例化一个按钮似乎很奇怪.

我想做的一件事是添加线,

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;

但我不知道如何创建具有该属性的可重用按钮.

即使这是创建可重复使用的自定义按钮的完全错误的方法,我显然需要提高我对对象的理解,因此我将非常感谢对我的误解的解释!

请?

fou*_*dry 9

您可以在不进行子类化的情况下执行此操作 - 通过创建类别(在Objective-C中执行操作的首选方式).使用类别,您可以为对象提供自定义方法,而无需对其进行子类化.您不能(轻松)提供自定义属性,但在您的情况下,这是不相关的.

使用类别

这是您的类别标题文件的外观:

//  UIButton+StyledButton.h

#import <UIKit/UIKit.h>

@interface UIButton (StyledButton)
- (void) styleButton; 
@end
Run Code Online (Sandbox Code Playgroud)

然后在实现文件中:

//
//  UIButton+StyledButton.m
//

#import "UIButton+StyledButton.h"

@implementation UIButton (StyledButton)

- (void) styleButton {
    //style your button properties here
    self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
Run Code Online (Sandbox Code Playgroud)

('self'指的是按钮对象,它也获取您在类别中编写的自定义方法.)

要使用它,#import "UIButton+StyledButton.h"那么你可以做这种事情......

on viewDidLoad {
    [super viewDidLoad];
    UIButton* myButton = [[UIButton alloc] initWithFrame:myFrame];
    [myButton styleButton];
}
Run Code Online (Sandbox Code Playgroud)

使用子类

子类的等价物看起来像这样:

头文件......

//  MyCustomButton.h

#import <UIKit/UIKit.h>

@interface MyCustomButton : UIButton
- (id)initWithCoder:(NSCoder *)coder;
- (id)initWithFrame:(CGRect)frame;
@end
Run Code Online (Sandbox Code Playgroud)

实施文件......

//  MyCustomButton.m

#import "MyCustomButton.h"

@implementation MyCustomButton

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

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

- (void) styleButton {
    //style your button properties here
    self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
Run Code Online (Sandbox Code Playgroud)

您提供了两个init方法 - initWithFrame是在代码中分配/启动对象时调用的方法; initWithCoder是从故事板或xib加载对象时系统调用的init方法.

要在代码中创建一个自定义按钮,您可以像任何其他对象一样分配/ init:

MyCustomButton* button = [[MyCustomButton alloc] initWithFrame:buttonFrame];
Run Code Online (Sandbox Code Playgroud)

您也不会分配/初始化超类实例,这是由initWithFrame:子类中的方法调用时完成的[super initWithFrame:frame].self指的是您的自定义子类实例,但它包含来自它的超类的所有(公共)属性和方法 - 除非您在子类中实现了覆盖.

要在storyboard/xib中使用子类按钮,只需拖出常规按钮,然后将其类型设置为Identity Inspector中的自定义按钮类.initWithCoder当按钮从storyboard/xib加载到视图中时,将自动调用该方法.

更新

从你的评论中,你似乎仍然存在一些困惑,所以这里有一些高度压缩的去混淆的笔记......

除非你真的知道你在做什么,否则远离子类化UINavigationController.这很少是必要的.

navController接口上的按钮是包含viewControllers的属性.查找navigationItem属性UIViewController(类似地 - 在UIToolbar视图控制器的情况下- 具有toolbarItems属性).这允许导航控制器具有上下文感知能力.

我的例子中的'viewDidLoad'被认为是常规的UIViewController.我的例子也对常规的类别UIBUtton具有没有正式关系UIBarButtonItem.

尝试获取UIButton类别以在尝试之前首先使用常规ViewController UIBarButtonItem(继承UIButton).

UIBarbuttonItem没有initWithFrame,因为组织栏(UINavigationBarUIToolbar)的东西 - 在这种情况下是导航控制器 - 负责它的最终尺寸和定位.viewController管理barButtonItems的相对顺序,以及它们是出现在左侧还是右侧,以及它的外观和(某些方面)外观,但其余部分由NavController决定.