Bem, para responder conceitualmente, seu cronômetro provavelmente deve ser uma subclasse de em UIView
vez de NSObject
.
Para instanciar uma instância do seu temporizador no IB, simplesmente arraste e UIView
solte-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 #import
sua 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 .xib
arquivo 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 .xib
arquivo.
Para testar isso, criei um novo vazio .xib
chamado "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 UIView
chamada "MyCustomTimer". No meu, .xib
eu 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 .h
arquivo 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 .xib
na minha UIView
subclasse. Usar um .xib
reduz 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 IBAction
métodos na MyCustomTimer
classe 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 MVC
e 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ê.