3

Ich habe ein Problem mit hidesBarOnSwipe Eigentum von UINavigationController.UINavigationController bidesBarOnSwipe Speicherleck Problem

Übersicht:

Link to project file

Ich habe einen Controller FirstViewController benannt, die Stammansicht von UINavigationController ist. Alles ist in Main.storyboard. FirstViewController enthält UIButton Aktion. Innerhalb dieser Aktion instanziiere ich einen SecondViewController und schiebe ihn auf einen Navigationsstapel.

- (IBAction)button:(id)sender { 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"]; 

    [self.navigationController pushViewController:vc animated:YES]; 
} 

Innen SecondViewController gibt es nur eine hidesBarsOnSwipe Eigenschaft auf YES auf viewDidLoad:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.navigationController.hidesBarsOnSwipe = YES; 
} 

und dealloc wird NSLogged:

- (void)dealloc { 
    NSLog(@"Dealloc"); 
} 

Problem:

Wenn wir wischen, um navigationBar zu verstecken, wird dealloc nie aufgerufen. Instruments zeigt hier ein SecondViewController-Speicherleck.

Wenn wir auf SecondViewController sind und wir drücken nur die Taste zurück - alles ist in Ordnung. Dealloc wird angerufen.

Es gibt definitiv eine Art von Retain-Zyklus, aber ich habe keine Ahnung, warum und wie man diese Art von Situation vermeiden kann.

+2

Habe gerade das gleiche Problem. Xcode 9.2 (Beta) –

+0

Dies scheint iOS 11+ Problem zu sein. Alles funktioniert gut auf iOS 10.3- –

Antwort

0

Einige Updates und temporäre Lösung:

Es gibt eine andere Methode navigationbar Versteck auszuführen. Was für mich gearbeitet zu bedienen:

[self.navigationController setNavigationBarHidden:hidden animated:YES]; 

Um das zu erreichen gute Ergebnisse eine Eigenschaft in der Klasse hinzufügen, um zu verfolgen Status navigationbar Animation:

@property (assign, nonatomic) BOOL statusBarAnimationInProgress; 

UIScrollViewDelegate wie folgt implementieren:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 
    CGFloat yVelocity = [scrollView.panGestureRecognizer velocityInView:scrollView].y; 
    if (yVelocity > 0 && !self.statusBarAnimationInProgress) { 
     [self setNavigationBarHidden:NO]; 
    } else if (yVelocity < 0 && !self.statusBarAnimationInProgress) { 
     [self setNavigationBarHidden:YES]; 
    } 
} 

Die unsichtbare Set-Navigationsleiste sollte wie folgt aussehen:

- (void)setNavigationBarHidden:(BOOL)hidden { 
    [CATransaction begin]; 
    self.statusBarAnimationInProgress = YES; 
    [CATransaction setCompletionBlock:^{ 
     self.statusBarAnimationInProgress = NO; 
    }]; 
    [self.navigationController setNavigationBarHidden:hidden animated:YES]; 
    [CATransaction commit]; 
} 

Ich benutze CATransaction, um zu überprüfen, ob die Animation der Navigationsleiste abgeschlossen ist. Jeder Weg, der funktioniert. Nicht so einfache Lösung, aber zumindest gibt es kein Leck :)