создать подкласс uibutton - PullRequest
       2

создать подкласс uibutton

6 голосов
/ 18 февраля 2011

Я попытался создать подкласс 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];

мой класс индикатора активности:

#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

Ответы [ 5 ]

10 голосов
/ 21 января 2012

Пользуйся композицией по наследству.

Создайте UIView, который содержит компоненты, которые вам нужны, и добавьте их в свой вид.

5 голосов
/ 14 января 2012

Я столкнулся с подобной ситуацией и согласен с Джеффом, что вам не нужно создавать подкласс 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;
}

И макет Subviews выглядел так:

- (void)layoutSubviews {
[super layoutSubviews];

// Get the size of the button
CGRect bounds = self.bounds;

// Configure the subviews of the "button"
...
}
2 голосов
/ 29 января 2013

Я создал пользовательский класс, предпочитая композицию наследованию, и она отлично работает.У моего пользовательского класса есть кнопка, и он знает, что это объект 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 
1 голос
/ 29 июня 2011

У вас есть довольно очевидная проблема, связанная с вашим методом dealloc: [super dealloc]; должен вызываться В КОНЦЕ вашей реализации, иначе строка после этого попытается получить доступ к пространству памяти (пространству ivar), которое уже было освобождено, так что это может привести к сбою.

Что касается другой проблемы, я не уверен, что было бы неплохо поместить монитор активности в качестве подпредставления кнопки в общем ...

0 голосов
/ 18 февраля 2011

Вы действительно не хотите подкласс UIButton.Это кластер классов, поэтому отдельные экземпляры будут похожи на UIRoundRectButton или на какой-то другой закрытый класс Apple.Что вы пытаетесь сделать, для чего нужен подкласс?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...