Ich bin mir bewusst, dass diese Frage schon einmal gestellt wurde, aber die Antworten sind widersprüchlich und ich bin verwirrt. Bitte flammen Sie mich nicht an.
Ich möchte eine wiederverwendbare UIView
Unterklasse in meiner App haben. Ich möchte die Schnittstelle mit einer NIB-Datei beschreiben.
Angenommen, es handelt sich um eine Ladeanzeige mit einem Aktivitätsindikator. Ich möchte in einem bestimmten Fall diese Ansicht instanziieren und in die Ansicht eines Ansichtscontrollers animieren. Ich könnte die Benutzeroberfläche der Ansicht problemlos programmgesteuert beschreiben, die Elemente programmgesteuert erstellen und ihren Frame innerhalb einer Init-Methode usw. festlegen.
Wie kann ich das mit einer Feder machen? Beibehalten der im Interface Builder angegebenen Größe, ohne einen Frame festlegen zu müssen.
Ich habe es so gemacht, aber ich bin mir sicher, dass es falsch ist (es ist nur eine Ansicht mit einem Picker):
- (id)initWithDataSource:(NSDictionary *)dataSource {
self = [super init];
if (self){
self = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@", [self class]] owner:self options:nil] objectAtIndex:0];
self.pickerViewData = dataSource;
[self configurePickerView];
}
return self;
}
Aber ich überschreibe mich selbst und wenn ich es instanziiere:
FSASelectView *selectView = [[FSASelectView alloc] initWithDataSource:selectViewDictionary];
selectView.delegate = self;
selectView.frame = CGRectMake(0, self.view.bottom + 50, [FSASelectView width], [FSASelectView height]);
Ich muss den Rahmen manuell einstellen, anstatt ihn von IB abholen zu lassen.
BEARBEITEN: Ich möchte diese benutzerdefinierte Ansicht in einem Ansichts-Controller erstellen und Zugriff auf die Elemente der Ansicht haben. Ich möchte keinen neuen View Controller.
Vielen Dank
EDIT: Ich weiß nicht, ob dies die beste Vorgehensweise ist, ich bin mir sicher, dass dies nicht der Fall ist, aber so habe ich es gemacht:
FSASelectView *selectView = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@",[FSASelectView class]] owner:self options:nil] objectAtIndex:0];
selectView.delegate = self;
[selectView configurePickerViewWithData:ds];
selectView.frame = CGRectMake(0, self.view.bottom + 50, selectView.width, selectView.height);
selectView.alpha = 0.9;
[self.view addSubview:selectView];
[UIView animateWithDuration: 0.25 delay: 0 options:UIViewAnimationOptionAllowUserInteraction |UIViewAnimationOptionCurveEaseInOut animations:^{
selectView.frame = CGRectMake(0, self.view.bottom - selectView.height, selectView.width, selectView.height);
selectView.alpha = 1;
} completion:^(BOOL finished) {
}];
Richtige Übung noch gewünscht
Sollte dies mit einem View Controller und Init mit dem Nib-Namen geschehen sein? Sollte ich die Schreibfeder in einer UIView-Initialisierungsmethode im Code gesetzt haben? Oder ist das, was ich getan habe, in Ordnung?
initWithDataSource
? Auf jeden Fall funktioniert dies auch dann, wenn Sie den Eigentümer als "Null" angeben.Antworten:
Ich verwende dies, um die wiederverwendbaren benutzerdefinierten Ansichten zu initialisieren, die ich habe.
Beachten Sie, dass Sie dort am Ende "firstObject" verwenden können, es ist etwas sauberer. "firstObject" ist eine praktische Methode für NSArray und NSMutableArray.
Hier ist ein typisches Beispiel für das Laden einer xib zur Verwendung als Tabellenkopf. In Ihrer Datei YourClass.m
Normalerweise
TopArea.xib
klicken Sie in der Datei auf Dateibesitzer und setzen den Dateieigentümer auf YourClass . Dann hätten Sie tatsächlich in YourClass.h IBOutlet-Eigenschaften. InTopArea.xib
können Sie Steuerelemente in diese Ausgänge ziehen.Vergessen Sie nicht, dass
TopArea.xib
Sie möglicherweise auf die Ansicht selbst klicken und diese auf eine Steckdose ziehen müssen, damit Sie bei Bedarf die Kontrolle darüber haben. (Ein sehr lohnender Tipp ist, dass Sie dies unbedingt für Tabellenzellenzeilen tun müssen - Sie müssen die Ansicht selbst mit der entsprechenden Eigenschaft in Ihrem Code verbinden.)quelle
Wenn Sie Ihr
CustomView
und seinxib
Verhalten unabhängig halten möchtenFile's Owner
, befolgen Sie diese SchritteFile's Owner
Feld leer.xib
Ihrer DateiCustomView
und legen Sie sieCustom Class
alsCustomView
(Name Ihrer benutzerdefinierten Ansichtsklasse) fest.IBOutlet
in.h
Datei Ihrer benutzerdefinierten Ansicht..xib
Klicken Sie in der Datei Ihrer benutzerdefinierten Ansicht auf Ansicht und gehen Sie hineinConnection Inspector
. Hier finden Sie alle Ihre IBOutlets, die Sie in einer.h
Datei definierenÜberschreiben Sie in der
.m
Datei IhrerCustomView
Klasse dieinit
Methode wie folgtWenn Sie jetzt Ihre laden möchten
CustomView
, verwenden Sie die folgende Codezeile[[CustomView alloc] init];
quelle
-init
. Stattdessen wirdinitWithFrame:
und aufgerufen-awakeFromNib
. Wenn Sie zum Laden Ihrer Ansicht denselben Code schreiben wie in der-init
Methode, geben Sie eine Endlosschleife ein.Befolgen Sie die folgenden Schritte
UIView
.MyView.xib
.UIViewController
vonNSObject
in xib. Siehe das Bild untenVerbinden Sie die Dateibesitzer-Ansicht mit Ihrer Ansicht. Siehe das Bild unten
Ändern Sie die Klasse Ihrer Ansicht in
MyView
. Gleich wie 3.Hier ist der Code zum Laden der Ansicht:
Ich hoffe es hilft.
Klarstellung :
UIViewController
wird verwendet, um Ihre xib zu laden und die Ansicht, die dieUIViewController
hat, ist tatsächlichMyView
die, die Sie in der MyView xib zugewiesen haben.Demo Ich habe eine Demo greifen gemacht hier
quelle
Beantwortung meiner eigenen Frage über 2 oder etwas Jahre später hier aber ...
Es wird eine Protokollerweiterung verwendet, sodass Sie für alle Klassen ohne zusätzlichen Code arbeiten können.
quelle
In Swift:
Der Name Ihrer benutzerdefinierten Klasse lautet beispielsweise
InfoView
Zuerst erstellen Sie Dateien
InfoView.xib
undInfoView.swift
so:Dann setzen Sie
File's Owner
aufUIViewController
diese mögen:Benennen Sie Ihre um
View
inInfoView
:Klicken
File's Owner
Sieview
mit der rechten Maustaste auf und verbinden Sie Ihr Feld mitInfoView
:Stellen Sie sicher, dass der Klassenname lautet
InfoView
:Danach können Sie die Schaltfläche "Aktion" in Ihrer benutzerdefinierten Klasse problemlos hinzufügen:
Und Verwendung dieser benutzerdefinierten Klasse in Ihrem
MainViewController
:quelle
Nun, Sie können entweder die xib mit einem View-Controller initialisieren und viewController.view verwenden. oder mach es so wie du es gemacht hast. Nur eine
UIView
Unterklasse als Controller zu erstellen,UIView
ist eine schlechte Idee.Wenn Sie in Ihrer benutzerdefinierten Ansicht keine Steckdosen haben, können Sie diese direkt mit einer
UIViewController
Klasse initialisieren.Update: In Ihrem Fall:
Andernfalls müssen Sie eine benutzerdefinierte
UIViewController
Datei erstellen (um sie als Eigentümer der Datei festzulegen, damit die Steckdosen ordnungsgemäß verkabelt sind).Wo immer Sie die Ansicht hinzufügen möchten, können Sie sie verwenden.
Es ist jedoch keine gute Idee, beim Laden der xib einen anderen Ansichts-Controller (der bereits für eine andere Ansicht verwendet wird) als Eigentümer zu übergeben, da die Ansichtseigenschaft des Controllers geändert wird und Sie nicht auf die ursprüngliche Ansicht zugreifen möchten habe einen Verweis darauf.
BEARBEITEN: Dieses Problem tritt auf, wenn Sie Ihre neue xib mit dem Eigentümer der Datei als derselben Hauptklasse eingerichtet
UIViewController
und die view-Eigenschaft mit der neuen xib-Ansicht verknüpft haben.dh;
Der folgende Code wird später Verwirrung stiften, wenn Sie ihn in die Ansicht schreiben, die geladen wurde
YourMainViewController
.self.view
Dies liegt daran, dass ab diesem Zeitpunkt auf Ihre benutzerdefinierte Ansicht verwiesen wirdquelle