我尝试将UIButton子类化为包含活动指示符,但是当我使用initWithFrame :(因为我是uibutton的子类我不使用buttonWithType :)按钮不显示。另外,在这种情况下我如何设置按钮类型?:
我的视图控制器:
ActivityIndicatorButton *button = [[ActivityIndicatorButton alloc] initWithFrame:CGRectMake(10, 10, 300, 44)];
[button addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"Older Posts..." forState: UIControlStateNormal];
[cell addSubview:button];
[button release];
my activityindicatorbutton class:
#import <Foundation/Foundation.h>
@interface ActivityIndicatorButton : UIButton {
UIActivityIndicatorView *_activityView;
}
-(void)startAnimating;
-(void)stopAnimating;
@end
@implementation ActivityIndicatorButton
- (id)initWithFrame:(CGRect)frame {
if (self=[super initWithFrame:frame]) {
_activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
_activityView.frame = CGRectOffset(_activityView.frame, 60.0f, 10.0f);
[self addSubview: _activityView];
}
return self;
}
-(void) dealloc{
[super dealloc];
[_activityView release];
_activityView = nil;
}
-(void)startAnimating {
[_activityView startAnimating];
}
-(void)stopAnimating {
[_activityView stopAnimating];
}
@end
答案 0 :(得分:10)
赞成合成而不是继承。
创建一个包含所需组件的UIView,并将它们添加到视图中。
答案 1 :(得分:5)
我遇到了类似的情况,并同意杰夫的说法,你真的不需要继承UIButton。我通过继承UIControl来解决这个问题,然后重写layoutSubviews来完成我想要的“按钮”视图的所有配置。这是一个更简单的实现,它继承了UIButton,因为似乎有一些隐藏的mojo在幕后进行。我的实现看起来像这样:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.opaque = YES;
self.imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
[self addSubview:self.imageView];
self.textLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[self addSubview:self.textLabel];
}
return self;
}
layoutSubviews看起来像这样:
- (void)layoutSubviews {
[super layoutSubviews];
// Get the size of the button
CGRect bounds = self.bounds;
// Configure the subviews of the "button"
...
}
答案 2 :(得分:2)
我创建了一个自定义类,更喜欢组合而不是继承,它完美无缺。我的自定义类有一个按钮,它知道它是MCContact对象。它还绘制一个合适的按钮,并使用传递的MCContact对象自动计算帧。
标头文件示例:
#import <UIKit/UIKit.h>
@protocol MCContactViewDelegate;
@interface MCContactView : UIView
{
}
@property (nonatomic, strong) MCContact *mcContact;
@property (nonatomic, weak) id <MCContactViewDelegate> delegate;
- (id)initWithContact:(MCContact*)mcContact delegate:(id <MCContactViewDelegate>)delegate;
@end
@protocol MCContactViewDelegate <NSObject>
- (void)contactViewButtonClicked:(MCContactView*)contactView;
@end
实施文件:
#import "MCContactView.h"
@interface MCContactView()
{
UIButton *_button;
}
@end
@implementation MCContactView
- (id)initWithContact:(MCContact*)mcContact delegate:(id <MCContactViewDelegate>)delegate
{
self = [super initWithFrame:CGRectZero];
if (self) {
GetTheme();
_mcContact = mcContact;
_delegate = delegate;
_button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *normalBackgroundImage = [[UIImage imageNamed:@"tokenNormal.png"] stretchableImageWithLeftCapWidth:12.5 topCapHeight:12.5];
[_button setBackgroundImage:normalBackgroundImage forState:UIControlStateNormal];
UIImage *highlightedBackgroundImage = [[UIImage imageNamed:@"tokenHighlighted.png"] stretchableImageWithLeftCapWidth:12.5 topCapHeight:12.5];
[_button setBackgroundImage:highlightedBackgroundImage forState:UIControlStateHighlighted];
_button.titleLabel.font = [theme contactButtonFont];
[_button setTitleColor:[theme contactButtonTextColor] forState:UIControlStateNormal];
[_button setTitleEdgeInsets:UIEdgeInsetsMake(4, 6, 4, 6)];
NSString *tokenString = ([allTrim(mcContact.name) length]>0) ? mcContact.name : mcContact.eMail;
[_button setTitle:tokenString forState:UIControlStateNormal];
[_button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
CGSize size = [tokenString sizeWithFont:[theme contactButtonFont]];
size.width += 20;
if (size.width > 200) {
size.width = 200;
}
size.height = normalBackgroundImage.size.height;
[_button setFrame:CGRectMake(0, 0, size.width, size.height)];
self.frame = _button.frame;
[self addSubview:_button];
}
return self;
}
- (void)buttonClicked:(id)sender
{
[self.delegate contactViewButtonClicked:self];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
@end
答案 3 :(得分:1)
你有一个非常明显的问题涉及你的dealloc方法:[super dealloc];必须在实现结束时调用,否则之后的行将尝试访问已经解除分配的内存空间(ivar空间),因此它将崩溃。
对于另一个问题,我不确定将活动监视器作为一般按钮的子视图是一个好主意......
答案 4 :(得分:-1)
你真的不想继承UIButton
。它是一个类集群,因此单个实例将类似于UIRoundRectButton
或其他一些私有Apple类。你想做什么,需要一个子类?