7

Miałem działający niestandardowy UIPresentationController przed Xcode beta 2 i iOS 10 beta 2. Nie zmieniłem żadnego kodu, ale prezentacja jest teraz prezentowana za pomocą standardowej prezentacji modalnej.Utrata odwołań do przeniesieniaDelegate przed prezentacją presetentation

Jest uwaga w przykładowym kodzie firmy Apple dla UIPresentationController który mówi:

Na prezentacji, która będzie wykorzystywać kontroler zwyczaj prezentacji, możliwe jest, że kontroler prezentacja być również transitioningDelegate. Zapobiega to wprowadzaniu kolejnego obiektu lub implementacji w kontrolerze widoku źródłowego .

transitioningDelegate nie posiada silne odniesienie do miejsca przeznaczenia object.To zapobiec presentationController od bycia wydany przed wywołaniem -presentViewController: animowane: Zakończenie: atrybut NS_VALID_UNTIL_END_OF_SCOPE jest dołączona do deklaracji .

Sprawdziłem przeniesienieDelegate na przedstawionym kontroler widoku przed i po prezentacji. Przed tym jest mój niestandardowy UIPresentationController, ale po nim jest zero. Domyślam się, że odwołanie jest wydawane, ale nie mogę znaleźć odpowiednika NS_VALID_UNTIL_END_OF_SCOPE w Swift. EDYTOWANIE: Sprawdziłem, że przeniesienieDelegate jest ustawione na chwilę przed prezentacją, a następnie jest zerowe, gdy nadejdzie czas przedstawienia.

Mój kod w kontrolerze widoku prezentowanie:

@IBAction func buttonAction(_ sender: UIButton) { 
    let secondViewController = storyboard!.instantiateViewController(withIdentifier: "NewViewController") as! NewViewController 
    let presentationController = MyPresentationController(presentedViewController: secondViewController, presenting: self) 
    presentationController.initialFrame = button.frame 
    secondViewController.transitioningDelegate = presentationController 

    // Move map 
    let pixelsToMove: CGFloat = mapView.frame.height/4 
    let region = self.mapView.region 

    self.mapView.setRegion(region, offsetBy: pixelsToMove, animated: true) 

    // Delegate to NewViewController 
    secondViewController.mapView = mapView 
    mapView.delegate = secondViewController 

    print(secondViewController.transitioningDelegate) 
    UIView.animate(withDuration: 0.3, animations: { 
     let tabBar = self.tabBarController!.tabBar 
     tabBar.frame.origin.y += tabBar.frame.height 

     self.present(secondViewController, animated: true, completion: nil) 
    }) 
} 

A mój kod w UIPresentationController:

override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) { 
    super.init(presentedViewController: presentedViewController, presenting: presentingViewController) 
    presentedViewController.modalPresentationStyle = .custom 
} 
+0

spróbuj zadeklarować presentationController przed zewnętrzną metodą. –

+0

Próbowałem, ale nadal mam ten sam problem. – jjatie

+0

spróbuj tego self.presentedViewController.transitioningDelegate –

Odpowiedz

2

Problem polegał na tym, że w metodzie beta 2 podpisy metod zostały zmienione w UIViewControllerTransitioningDelegate, więc nie zostały wywołane w moim kodzie. Nie rozumiem dlaczego, ale po raz kolejny wszystko działa idealnie bez wyraźnego przechowywania silnego odniesienia do kontrolera prezentacji.

+0

To był mój problem. Protokół delegatów ma wszystkie funkcje opcjonalne, więc moje funkcje z niepoprawnymi podpisami zostały po cichu zignorowane. Aby uzyskać więcej informacji, zobacz: http://stackoverflow.com/a/39513247/959896 –

2

Obiekt transitioningDelegate jest weak var. Zobacz docs here. Oznacza to, że licznik zatrzymania dla presentationController nie zostanie zwiększony po ustawieniu secondViewController.transitioningDelegate = presentationController. Ponieważ tworzysz w tej metodzie presentationController, a nic więcej nie ma silnego odniesienia do tego obiektu, jego liczba zostanie zatrzymana na 0 i będzie zerowa, jak tylko zostanie zwrócone sterowanie z tej funkcji (zaraz po print(secondViewController.transitioningDelegate), ponieważ UIView.animate(...) jest asynchroniczne) .

Będziesz potrzebować czegoś, aby zachować silne odniesienie do presentationController podczas prezentacji kontrolera widoku. Jeśli coś mocno trzyma się odniesienia, liczba zatrzymań nie spadnie poniżej 1, dopóki nie ustawisz tego odnośnika na nil. Jednym z rozwiązań byłoby zachowanie go jako własności bieżącej klasy lub własności secondViewController.

+0

Spróbuję tego dzisiaj. Dlaczego miałoby działać w iOS 10 beta 1 i 9.3.x bez tworzenia silnego odniesienia do niego? – jjatie

+0

Niestety, nie jestem pewien. Domyślam się, że to też by nie zadziałało wcześniej. – keithbhunter

+0

Próbowałem przechowywać go z silnym odniesieniem w prezentowaniu, prezentowaniu i przedstawianiu kontrolerów, a przemiana delokalizacji wciąż staje się zerowa w trakcie prezentacji – jjatie