1

我是 Xcode 和目标 c 的新手。我想创建一个具有特定外观的按钮(可能是一个 UIBarButtonItem,用于导航栏),我将在不同的视图中重复使用它。我已经搜索了很长时间,但无法弄清楚如何。

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

我想做的一件事是添加该行,

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;

但我不知道如何使用该属性创建可重用按钮。

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

请?

4

1 回答 1

9

您可以在没有子类化的情况下做到这一点 - 通过创建一个类别(在 Objective-C 中做事的首选方式)。使用类别,您可以为对象提供自定义方法,而无需对其进行子类化。您不能(轻松)提供自定义属性,但在您的情况下,这无关紧要。

使用类别

这是您的类别头文件的外观:

//  UIButton+StyledButton.h

#import <UIKit/UIKit.h>

@interface UIButton (StyledButton)
- (void) styleButton; 
@end

然后在实现文件中:

//
//  UIButton+StyledButton.m
//

#import "UIButton+StyledButton.h"

@implementation UIButton (StyledButton)

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

(‘self’指的是按钮对象,它也获取了你在类中编写的自定义方法。)

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

on viewDidLoad {
    [super viewDidLoad];
    UIButton* myButton = [[UIButton alloc] initWithFrame:myFrame];
    [myButton styleButton];
}

使用子类

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

头文件...

//  MyCustomButton.h

#import <UIKit/UIKit.h>

@interface MyCustomButton : UIButton
- (id)initWithCoder:(NSCoder *)coder;
- (id)initWithFrame:(CGRect)frame;
@end

实现文件...

//  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;
}

您提供了两个初始化方法 -initWithFrame是在代码中分配/初始化对象时调用的方法;initWithCoder如果从情节提要或 xib 加载对象,则系统调用的 init 方法。

要在代码中创建您的自定义按钮之一,您可以像处理任何其他对象一样分配/初始化:

MyCustomButton* button = [[MyCustomButton alloc] initWithFrame:buttonFrame];

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

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

更新

从您的评论来看,您似乎仍然存在一些困惑,所以这里有一些高度压缩的去混淆注释......

远离继承 UINavigationController 除非你真的知道你在做什么。很少有必要。

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

我的示例中的“viewDidLoad”假定为常规UIViewController. 我的例子也是常规的一个类别,UIBUttonUIBarButtonItem.

在尝试之前先尝试让 UIButton 类别与常规 ViewController 一起使用UIBarButtonItem(它不继承UIButton)。

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

于 2013-03-16T21:51:25.407 回答