Cóż, odpowiadając koncepcyjnie, twój licznik czasu powinien być prawdopodobnie podklasą UIView
zamiast NSObject
.
Aby utworzyć instancję timera w IB, po prostu przeciągnij i UIView
upuść ją w widoku kontrolera widoku i ustaw jej klasę na nazwę klasy timera.
Pamiętaj by #import
klasie licznika czasu w kontrolerze widoku.
Edycja: dla projektu IB (dla tworzenia instancji kodu zobacz historię wersji)
W ogóle nie jestem zaznajomiony ze scenorysami, ale wiem, że możesz skonstruować swój interfejs w IB, używając .xib
pliku, który jest prawie identyczny z używaniem wersji storyboardowej; Powinieneś nawet być w stanie skopiować i wkleić swoje widoki jako całość z istniejącego interfejsu do.xib
pliku.
Aby to przetestować, utworzyłem nowy pusty o .xib
nazwie „MyCustomTimerView.xib”. Następnie dodałem widok, a do tego dodałem etykietę i dwa przyciski. Tak jak tak:
Stworzyłem nową podklasę klasy celu C o UIView
nazwie „MyCustomTimer”. W moim .xib
ustawiłem klasę właściciela mojego pliku na MyCustomTimer . Teraz mogę łączyć akcje i gniazda, tak jak każdy inny widok / kontroler. Wynikowy .h
plik wygląda następująco:
@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
Jedyną przeszkodą, jaka mi pozostała, jest uzyskanie tego .xib
w mojej UIView
podklasie. Używanie a .xib
radykalnie zmniejsza wymaganą konfigurację. A ponieważ używasz scenorysów do ładowania timerów, o których wiemy, że -(id)initWithCoder:
jest to jedyny inicjator, który zostanie wywołany. Oto jak wygląda plik implementacji:
#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
Metoda o nazwie loadNibNamed:owner:options:
robi dokładnie to, na co wygląda. Ładuje końcówkę i ustawia właściwość „Właściciel pliku” na siebie. Wyodrębniamy pierwszy obiekt w tablicy i jest to widok główny stalówki. Dodajemy widok jako podwidok i Voila jest na ekranie.
Oczywiście zmienia to tylko kolor tła etykiety, gdy naciskane są przyciski, ale ten przykład powinien pomóc Ci dobrze działać.
Uwagi na podstawie komentarzy:
Warto zauważyć, że jeśli masz problemy z nieskończoną rekurencją, prawdopodobnie przegapiłeś subtelną sztuczkę tego rozwiązania. Nie robi tego, co myślisz, że robi. Widok umieszczony w serii ujęć nie jest widoczny, ale zamiast tego ładuje inny widok jako widok podrzędny. Widok, który ładuje, jest widokiem zdefiniowanym w końcówce. „Właścicielem pliku” w końcówce jest ten niewidoczny widok. Fajne jest to, że ten niewidoczny widok jest nadal klasą Objective-C, która może być używana jako swego rodzaju kontroler widoku dla widoku, który przynosi ze stalówki. Na przykład IBAction
metody w MyCustomTimer
klasie są czymś, czego można oczekiwać bardziej w kontrolerze widoku niż w widoku.
Na marginesie, niektórzy mogą twierdzić, że to się psuje MVC
i częściowo się z tym zgadzam. Z mojego punktu widzenia jest to bardziej związane z niestandardowym UITableViewCell
, który czasami musi być częściowo kontrolerem.
Warto też zauważyć, że ta odpowiedź miała dostarczyć bardzo konkretnego rozwiązania; utwórz jedną końcówkę, której wystąpienie można utworzyć wiele razy w tym samym widoku, co w scenorysie. Na przykład, możesz łatwo wyobrazić sobie sześć z tych timerów jednocześnie na ekranie iPada. Jeśli potrzebujesz tylko określić widok dla kontrolera widoku, który ma być używany wiele razy w Twojej aplikacji, to rozwiązanie dostarczone przez jyavenard na to pytanie jest prawie na pewno lepszym rozwiązaniem dla Ciebie.