Bem, para responder conceitualmente, seu cronômetro provavelmente deve ser uma subclasse de em UIViewvez de NSObject.
Para instanciar uma instância do seu temporizador no IB, simplesmente arraste e UIViewsolte-o na visualização do seu controlador de visualização e defina sua classe com o nome da classe do seu temporizador.

Lembre-se de #importsua classe de cronômetro em seu controlador de visualização.
Editar: para design IB (para instanciação de código, consulte o histórico de revisão)
Não estou muito familiarizado com o storyboard, mas sei que você pode construir sua interface em IB usando um .xibarquivo que é quase idêntico ao da versão do storyboard; Você deve até mesmo ser capaz de copiar e colar suas visualizações como um todo da interface existente para o .xibarquivo.
Para testar isso, criei um novo vazio .xibchamado "MyCustomTimerView.xib". Em seguida, adicionei uma visualização e a ela adicionei um rótulo e dois botões. Igual a:

Criei uma nova subclasse de classe Objectiva C UIViewchamada "MyCustomTimer". No meu, .xibeu defini minha classe Proprietário do arquivo como MyCustomTimer . Agora estou livre para conectar ações e tomadas como qualquer outra visualização / controlador. O .harquivo resultante tem a seguinte aparência:
@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
O único obstáculo que falta superar é colocar isso .xibna minha UIViewsubclasse. Usar um .xibreduz drasticamente a configuração necessária. E como você está usando storyboards para carregar os cronômetros, sabemos que -(id)initWithCoder:é o único inicializador que será chamado. Então, aqui está a aparência do arquivo de implementação:
#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
O método nomeado loadNibNamed:owner:options:faz exatamente o que parece. Ele carrega o Nib e define a propriedade "Proprietário do arquivo" como self. Extraímos o primeiro objeto do array e essa é a visão raiz do Nib. Adicionamos a visualização como uma subvisualização e Voila está na tela.
Obviamente, isso apenas muda a cor de fundo do rótulo quando os botões são pressionados, mas este exemplo deve ajudá-lo no bom caminho.
Notas baseadas em comentários:
É importante notar que, se você está tendo problemas de recursão infinita, provavelmente não percebeu o truque sutil dessa solução. Não está fazendo o que você pensa que está fazendo. A visão que é colocada no storyboard não é vista, mas em vez disso carrega outra visão como uma subvisualização. A visualização que ele carrega é a visualização definida na ponta. O "proprietário do arquivo" na ponta é aquela visão invisível. A parte legal é que essa visão invisível ainda é uma classe Objective-C que pode ser usada como uma espécie de controlador de visão para a visão que ela traz da ponta. Por exemplo, os IBActionmétodos na MyCustomTimerclasse são algo que você esperaria mais em um controlador de visualização do que em uma visualização.
Como uma observação lateral, alguns podem argumentar que isso quebra MVCe eu concordo um pouco. Do meu ponto de vista, está mais relacionado a um costume UITableViewCell, que às vezes também precisa ser parte do controlador.
É importante notar também que essa resposta foi para fornecer uma solução muito específica; crie uma ponta que pode ser instanciada várias vezes na mesma visualização em um storyboard. Por exemplo, você pode facilmente imaginar seis desses temporizadores, todos em uma tela de iPad ao mesmo tempo. Se você só precisa especificar uma visualização para um controlador de visualização que deve ser usado várias vezes em seu aplicativo, a solução fornecida por jyavenard para esta questão é quase certamente uma solução melhor para você.