Хорошо, чтобы ответить концептуально, ваш таймер, вероятно, должен быть подклассом UIView
вместо NSObject
.
Чтобы создать экземпляр вашего таймера в IB, просто перетащите UIView
, перетащите его на представление контроллера вашего представления и установите для его класса имя класса вашего таймера.
Не забудьте #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:
делает именно то, что кажется. Он загружает Nib и устанавливает для свойства «Владелец файла» значение self. Мы извлекаем первый объект в массиве, и это корневое представление Nib. Мы добавляем вид как подпредставление, и вуаля, это на экране.
Очевидно, это просто меняет цвет фона ярлыка при нажатии кнопок, но этот пример должен помочь вам в этом.
Примечания на основе комментариев:
Стоит отметить, что если вы получаете бесконечные проблемы рекурсии, вы, вероятно, пропустили тонкий трюк этого решения. Это не делает то, что вы думаете, что делает. Представление, помещенное в раскадровку, не отображается, а загружает другое представление как подпредставление. Это представление, которое он загружает, является видом, который определен в кончике. «Владелец файла» в кончике - это невидимое представление. Крутая часть в том, что это невидимое представление по-прежнему является классом Objective-C, который можно использовать в качестве контроллера вида для представления, которое он вводит из пера. Например, методы IBAction
в классе MyCustomTimer
- это то, что вы ожидаете большего в контроллере представления, чем в представлении.
В качестве примечания, некоторые могут утверждать, что это нарушает MVC
, и я в чем-то согласен. С моей точки зрения, это более тесно связано с пользовательским UITableViewCell
, который также иногда должен быть частичным контроллером.
Стоит также отметить, что этот ответ должен был дать очень конкретное решение; создайте одно перо, которое можно создать несколько раз в том же представлении , как показано на раскадровке. Например, вы можете легко представить шесть таких таймеров одновременно на экране iPad. Если вам нужно только указать представление для контроллера представления, который будет использоваться несколько раз в вашем приложении, тогда решение, предоставленное jyavenard для этого вопроса , почти наверняка будет лучшим решением для вас.