Beim Anpassen der Ansicht zu beachtende Probleme

Schwerpunkt dieses Artikels

  • Informationen zur Initialisierungsmethode der benutzerdefinierten Ansicht
  • Über addSubview
  • Über Rahmen und Grenzen

Informationen zur Initialisierungsmethode der benutzerdefinierten Ansicht

Normalerweise erstellen wir eine private Methode namens createUI , um die Unteransicht zu erstellen , die für die aktuelle benutzerdefinierte Ansicht erforderlich ist . In welche Methode setzen Sie createUI ein?

  • drin()?
  • initWithFrame()?

Anweisungen zur Überprüfung: Rufen Sie zunächst die Methode createUI in der Init- Methode von CustomView auf .

- (instancetype)init {
    if (self = [super init]) {
        [self createUI];
    }
    return self;
}

- (void)createUI {
    [self addSubview:self.testView];
}

- (UIView *)testView {
    if (!_testView) {
        _testView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        _testView.backgroundColor = [UIColor redColor];
    }
    return _testView;
}

Erstellen Sie CustomView extern in Form von init:

    _ceshiView = [[CeShiView alloc] init];
    _ceshiView.frame = CGRectMake(100, 100, 200, 200);
    _ceshiView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:_ceshiView];

CustomView und seine Unteransichten können normal angezeigt werden.

Es gibt jedoch ein Problem: Wenn die Außenseite in Form von initWithFrame erstellt wird, kann die Methode createUI nicht aufgerufen werden, sodass die Unteransicht nicht angezeigt werden kann .

Die Methode createUI wird sowohl in der Methode init als auch in der Methode initWithFrame aufgerufen . Zählen Sie die Anzahl der Aufrufe der createUI -Methode.

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self createUI];
    }
    return self;
}

- (instancetype)init {
    if (self = [super init]) {
        [self createUI];
    }
    return self;
}

- (void)createUI {
    NSLog(@"SubViews Add");
    [self addSubview:self.testView];
      for (NSInteger i = 0; i < 100; i++) {
        [self addSubview:self.testView];
    }
    
    NSLog(@"subviewsCount = 【%ld】",self.subviews.count);
    for (UIView *view in self.subviews) {
           NSLog(@"subView 【%@】",view);
    }
}

- (UIView *)testView {
    if (!_testView) {
        _testView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        _testView.backgroundColor = [UIColor redColor];
    }
    return _testView;
}

@end

Schließlich erfuhr ich, dass createUI zweimal aufgerufen wurde.

2022-01-12 17:06:43.112130+0800 WJ_KVO[8774:258969] SubViews Add
2022-01-12 17:06:43.113792+0800 WJ_KVO[8774:258969] SubViews Add

Ruft die init-Methode der benutzerdefinierten Ansicht standardmäßig die initWithFrame-Methode auf?

1. Suchen Sie dynamisch die Init-Methode von CustomView

2. Rufen Sie die Methode [super init] auf

3. Was intern in der Super-Init-Methode ausgeführt wird, ist [super initWithFrame:CGRectZero]

4. Wenn Super feststellt, dass CustomView die initWithFrame-Methode implementiert

5. Wenden Sie sich an, um die initWithFrame-Methode von self (CustomView) auszuführen.

6. Führen Sie abschließend den Rest von init aus

Hier kann auch eine Schlussfolgerung überprüft werden : Super in OC ermöglicht tatsächlich einer bestimmten Klasse, die Methode der übergeordneten Klasse aufzurufen, anstatt dass die übergeordnete Klasse eine bestimmte Methode aufruft. Die Methode ruft die Prozesssequenz dynamisch auf.

Bottom-up (dies ist auch der Grund, warum createUI nicht nur in der Init- Methode mehrmals ausgeführt wird, da der initWithFrame der übergeordneten Klasse die CreateUI- Operation nicht ausführt ).

Fazit: Die Methode createUI wird am besten in initWithFrame aufgerufen. Die Methode createUI kann normal mit init oder initWithFrame extern ausgeführt werden. Nicht anpassen

Schreiben Sie init und initWithFrame gleichzeitig in View neu und führen Sie denselben View-Layout-Code aus. Führt dazu, dass der Layoutcode (createUI) mehrmals ausgeführt wird.

Über addSubview

Durch mehrmaliges Hinzufügen derselben Ansicht entstehen keine Situationen mit mehreren Ebenen .

In der Dokumentation für addSubview heißt es, dass View nur eine übergeordnete Ansicht hat. Wenn sich die neue übergeordnete Ansicht von der ursprünglichen übergeordneten Ansicht unterscheidet, wird die Ansicht aus der ursprünglichen Ansicht entfernt und der neuen Ansicht hinzugefügt.

22-01-12 17:22:35.726706+0800 WJ_KVO[8970:267845] subviewsCount = 【1】
2022-01-12 17:22:35.726799+0800 WJ_KVO[8970:267845] subView 【<UIView: 0x7f78a7f075f0; frame = (0 0; 100 100); layer = <CALayer: 0x6000013c9960>>】

Wie im obigen Ausdruck gezeigt, verfügt CeshiView immer nur über eine Unteransicht (testView).

Folgende Annahmen können getroffen werden:

1. Entfernen Sie die Unteransicht aus der alten übergeordneten Ansicht und fügen Sie die Unteransicht dann erneut zur übergeordneten Ansicht hinzu.

2. Bestimmen Sie, ob die alte und die neue übergeordnete Ansicht konsistent sind. Wenn sie konsistent sind, wird kein Vorgang ausgeführt.

Fazit : Wenn die übergeordnete Ansicht wiederholt dieselbe Unteransicht hinzufügt, treten keine Situationen mit mehreren Ebenen auf. Da testView in diesem Beispiel in Form von Lazy Loading erstellt wird , wird jedes Mal dieselbe Ansicht von self hinzugefügt. Wenn es jedoch in der Form von UIView *testView = [UIView alloc] initWithFrame in createUI erstellt wird , werden mehrere Ansichten erstellt erstellt. Hierarchische Ansicht .

Zusammenfassung: Es ist am besten, Unteransichten benutzerdefinierter Ansichten in Form von Lazy Loading zu erstellen, um Ausnahmen zu vermeiden, die durch andere unsachgemäße Schreibweisen verursacht werden.

Über Rahmen und Bindung

Es gibt zwei sehr wichtige Attribute bezüglich der Position in iOSUI-Steuerelementen: Rahmen und Grenze.

[Externer Link Bildübertragung fehlgeschlagen. Die Quellseite verfügt möglicherweise über einen Anti-Leeching-Mechanismus. Es wird empfohlen, das Bild zu speichern und direkt hochzuladen (img-7He9Zeod-1642056027779)(/Users/yichen/Library/Application Support/typora-user -images/image-20220112172848089 .png)]

Frame:Hier entspricht die Ansicht hauptsächlich der übergeordneten Ansicht.

bound:Dies ist die Position der Ansicht relativ zum Steuerelement selbst.

center:Dies ist die Mittelposition relativ zum übergeordneten Ansichtssteuerelement.

Wir können die Position und Größe der oberen linken Ecke des Steuerelements über Frame.origin/bounds.origin und Frame.size/bounds.size zurückgeben

Supongo que te gusta

Origin blog.csdn.net/weixin_42357849/article/details/122473531
Recomendado
Clasificación