Erstellen einer wiederverwendbaren UIView mit xib (und Laden vom Storyboard)

OK, es gibt Dutzende von posts auf StackOverflow über diese, aber keine ist besonders klar auf die Lösung. Ich möchte erstellen Sie eine benutzerdefinierte UIView mit einer begleitenden xib-Datei. Die Anforderungen sind:

  • Keine separate UIViewController – eine völlig eigenständige Klasse
  • Filialen in der Klasse, mir zu erlauben, set - /get-Eigenschaften der Ansicht

Meinem aktuellen Ansatz, um dies zu tun, ist:

  1. Überschreiben -(id)initWithFrame:
    -(id)initWithFrame:(CGRect)frame {
        self = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class])
                                              owner:self
                                            options:nil] objectAtIndex:0];
        self.frame = frame;
        return self;
    }
  2. Instanziieren programmgesteuert mithilfe -(id)initWithFrame: in meinem view controller
    MyCustomView *myCustomView = [[MyCustomView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
    [self.view insertSubview:myCustomView atIndex:0];

Dies funktioniert gut (obwohl nie Anrufe [super init] und einfache Einstellung auf das Objekt mit dem Inhalt der geladenen Spitze scheint ein wenig den Verdacht – es ist ein Ratschlag hier, um fügen Sie eine Untersicht in diesem Falldie auch gut funktioniert). Aber ich möchte in der Lage sein zu instanziieren der view aus dem storyboard auch. Also ich kann:

  1. Ort ein UIView auf einer übergeordneten Ansicht in der storyboard -
  2. Festlegen der benutzerdefinierten Klasse MyCustomView
  3. Überschreiben -(id)initWithCoder: – den code habe ich gesehen, die meisten oft passt ein Muster wie das folgende:
    -(id)initWithCoder:(NSCoder *)aDecoder {
        self = [super initWithCoder:aDecoder];
        if (self) {
            [self initializeSubviews];
        }
        return self;
    }
    
    -(id)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            [self initializeSubviews];
        }
        return self;
    }
    
    -(void)initializeSubviews {
        typeof(view) view = [[[NSBundle mainBundle]
                             loadNibNamed:NSStringFromClass([self class])
                                    owner:self
                                  options:nil] objectAtIndex:0];
        [self addSubview:view];
    }

Natürlich, dies funktioniert nicht, als ob ich den Ansatz oben, oder ob ich instanziieren programmatisch, beide am Ende den rekursiven Aufruf -(id)initWithCoder: beim betreten -(void)initializeSubviews und laden der nib-Datei.

Einigen anderen Fragen befassen sich mit diese wie hierhierhier und hier. Jedoch, keine der Antworten ist zufriedenstellend behebt das problem:

  • Einen gemeinsamen Vorschlag zu sein scheint, das einbetten der gesamten Klasse in einem UIViewController, und tun das nib laden gibt, aber dies scheint nicht optimal zu mir, denn es erfordert das hinzufügen einer weiteren Datei nur als wrapper

Könnte jemand Ratschläge geben, wie dieses problem zu beheben, und erhalten Sie die Arbeit Verkaufsstellen in einem benutzerdefinierten UIView mit minimalem Aufwand/keine dünne controller wrapper? Oder gibt es eine alternative, die sauberer Art, die Dinge mit mindestens boilerplate-code?

InformationsquelleAutor der Frage Ken Chatfield | 2014-02-20

Schreibe einen Kommentar