Чтобы ответить концептуально, ваш таймер, скорее всего, должен быть подклассом UIView
вместо NSObject
.
Чтобы создать экземпляр вашего таймера в IB, просто перетащите UIView
его на представление вашего контроллера представления и установите его class равным имени вашего класса таймера.
Не забудьте указать #import
свой класс таймера в контроллере представления.
Изменить: для дизайна IB (для создания экземпляра кода см. Историю изменений)
Я совсем не знаком с раскадровкой, но я знаю, что вы можете создать свой интерфейс в IB, используя .xib
файл, который почти идентичен использованию версии раскадровки; Вы даже должны иметь возможность копировать и вставлять свои представления целиком из существующего интерфейса в .xib
файл.
Чтобы проверить это, я создал новый пустой .xib
файл с именем «MyCustomTimerView.xib». Затем я добавил представление, к которому добавил метку и две кнопки. Вот так:
Я создал новый подкласс класса объектного C под UIView
названием «MyCustomTimer». В моем .xib
я установил для своего класса владельца файла значение MyCustomTimer . Теперь я могу подключать действия и выходы, как и любой другой вид / контроллер. Полученный .h
файл выглядит так:
@interface MyCustomTimer : UIView
@property (strong, nonatomic) IBOutlet UILabel *displayLabel;
@property (strong, nonatomic) IBOutlet UIButton *startButton;
@property (strong, nonatomic) IBOutlet UIButton *stopButton;
- (IBAction)startButtonPush:(id)sender;
- (IBAction)stopButtonPush:(id)sender;
@end
Единственное препятствие, которое нужно преодолеть, - это получить это .xib
на моем UIView
подклассе. Использование .xib
значительно сокращает требуемые настройки. И поскольку вы используете раскадровки для загрузки таймеров, мы знаем, -(id)initWithCoder:
что это единственный инициализатор, который будет вызван. Итак, вот как выглядит файл реализации:
#import "MyCustomTimer.h"
@implementation MyCustomTimer
@synthesize displayLabel;
@synthesize startButton;
@synthesize stopButton;
-(id)initWithCoder:(NSCoder *)aDecoder{
if ((self = [super initWithCoder:aDecoder])){
[self addSubview:
[[[NSBundle mainBundle] loadNibNamed:@"MyCustomTimerView"
owner:self
options:nil] objectAtIndex:0]];
}
return self;
}
- (IBAction)startButtonPush:(id)sender {
self.displayLabel.backgroundColor = [UIColor greenColor];
}
- (IBAction)stopButtonPush:(id)sender {
self.displayLabel.backgroundColor = [UIColor redColor];
}
@end
Названный метод loadNibNamed:owner:options:
делает именно то, что кажется. Он загружает Перо и устанавливает для свойства «Владелец файла» значение self. Мы извлекаем первый объект в массиве, который является корневым представлением Nib. Мы добавляем представление как подвид, и вуаля оно отображается на экране.
Очевидно, это просто меняет цвет фона метки при нажатии кнопок, но этот пример должен помочь вам в этом.
Примечания на основе комментариев:
Стоит отметить, что если у вас возникают проблемы с бесконечной рекурсией, вы, вероятно, упустили тонкую уловку этого решения. Он не делает то, что вы думаете. Представление, помещенное в раскадровку, не отображается, а вместо этого загружает другое представление как подпредставление. Это представление, которое он загружает, определено в пере. «Владелец файла» в пере - это невидимое изображение. Крутая часть заключается в том, что это невидимое представление по-прежнему является классом Objective-C, который можно использовать как своего рода контроллер представления для представления, которое он приносит из пера. Например, IBAction
методы в MyCustomTimer
классе - это то, чего вы ожидаете больше от контроллера представления, чем от представления.
В качестве примечания, некоторые могут возразить, что это не работает, MVC
и я в чем-то согласен. С моей точки зрения, это более тесно связано с кастомом UITableViewCell
, который также иногда должен быть частью контроллера.
Также стоит отметить, что этот ответ должен был предоставить очень конкретное решение; создайте один наконечник, который можно создавать несколько раз в одном и том же виде, что и на раскадровке. Например, вы легко можете представить шесть из этих таймеров одновременно на экране iPad. Если вам нужно только указать представление для контроллера представления, который будет использоваться несколько раз в вашем приложении, то решение, предоставленное jyavenard для этого вопроса , почти наверняка будет лучшим решением для вас.