Utworzyłem interaktywne przejście. Mój func animateTransition(transitionContext: UIViewControllerContextTransitioning)
jest całkiem normalny, dostaję pojemnik UIView
, dodaję dwa UIViewControllers
, a następnie robię zmiany animacji w UIView.animateWithDuration(duration, animations, completion)
.UIPercentDrivenInteractiveTransition nie przechodzi do zakończenia animacji szybkim gestem
Dodaję UIScreenEdgePanGestureRecognizer
do mojej z UIViewController
. Działa dobrze, z wyjątkiem sytuacji, gdy wykonuję bardzo szybką patelnię.
W tym ostatnim scenariuszu aplikacja nie reaguje, wciąż jest na tym samym UIViewController
(przejście prawdopodobnie nie zadziałało), ale uruchamiane są zadania w tle. Po uruchomieniu Debug View Hierarchy
widzę nowy UIViewController
zamiast poprzedniego, a poprzedni (przynajmniej jego UIView
) stoi tam, gdzie powinien stanąć na końcu przejścia.
Zrobiłem kilka wydrukować i sprawdzić punkty i od tego, co mogę powiedzieć, że kiedy pojawia się problem, zakończenie animacji za (jeden w moim sposobie animateTransition
) nie zostanie osiągnięta, więc nie mogę wywołać metodę transitionContext.completeTransition
aby zakończyć lub nie przejść.
Widziałem również, że patelnia czasami przechodzi od UIGestureRecognizerState.Began
prosto do UIGestureRecognizerState.Ended
bez przechodzenia przez UIGestureRecognizerState.Changed
.
Kiedy przechodzi UIGestureRecognizerState.Changed
, zarównotranslation
ivelocity
pozostają takie same dla każdego UIGestureRecognizerState.Changed
stanach.
EDIT:
Oto kod:
animateTransition
metoda
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
self.transitionContext = transitionContext
let containerView = transitionContext.containerView()
let screens: (from: UIViewController, to: UIViewController) = (transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!, transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!)
let parentViewController = presenting ? screens.from : screens.to
let childViewController = presenting ? screens.to : screens.from
let parentView = parentViewController.view
let childView = childViewController.view
// positionning the "to" viewController's view for the animation
if presenting {
offStageChildViewController(childView)
}
containerView.addSubview(parentView)
containerView.addSubview(childView)
let duration = transitionDuration(transitionContext)
UIView.animateWithDuration(duration, animations: {
if self.presenting {
self.onStageViewController(childView)
self.offStageParentViewController(parentView)
} else {
self.onStageViewController(parentView)
self.offStageChildViewController(childView)
}}, completion: { finished in
if transitionContext.transitionWasCancelled() {
transitionContext.completeTransition(false)
} else {
transitionContext.completeTransition(true)
}
})
}
gest gest i obsługi:
weak var fromViewController: UIViewController! {
didSet {
let screenEdgePanRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: "presentingViewController:")
screenEdgePanRecognizer.edges = edge
fromViewController.view.addGestureRecognizer(screenEdgePanRecognizer)
}
}
func presentingViewController(pan: UIPanGestureRecognizer) {
let percentage = getPercentage(pan)
switch pan.state {
case UIGestureRecognizerState.Began:
interactive = true
presentViewController(pan)
case UIGestureRecognizerState.Changed:
updateInteractiveTransition(percentage)
case UIGestureRecognizerState.Ended:
interactive = false
if finishPresenting(pan, percentage: percentage) {
finishInteractiveTransition()
} else {
cancelInteractiveTransition()
}
default:
break
}
}
pojęcia, co może się zdarzyć?
EDIT 2:
Oto nieujawnione metody:
override func getPercentage(pan: UIPanGestureRecognizer) -> CGFloat {
let translation = pan.translationInView(pan.view!)
return abs(translation.x/pan.view!.bounds.width)
}
override func onStageViewController(view: UIView) {
view.transform = CGAffineTransformIdentity
}
override func offStageParentViewController(view: UIView) {
view.transform = CGAffineTransformMakeTranslation(-view.bounds.width/2, 0)
}
override func offStageChildViewController(view: UIView) {
view.transform = CGAffineTransformMakeTranslation(view.bounds.width, 0)
}
override func presentViewController(pan: UIPanGestureRecognizer) {
let location = pan.locationInView((fromViewController as! MainViewController).tableView)
let indexPath = (fromViewController as! MainViewController).tableView.indexPathForRowAtPoint(location)
if indexPath == nil {
pan.state = .Failed
return
}
fromViewController.performSegueWithIdentifier("chartSegue", sender: pan)
}
- usunąć linie "Over", dodając => nie rozwiąże to
- dodałem
updateInteractiveTransition
w.Began
, w.Ended
, w obu => go nie naprawiono - Włączony powinienRasteryzować na warstwie widoku mojego
toViewController
i niech go na cały czas => nie go naprawić
Ale pytanie brzmi, dlaczego, kiedy robi szybki interaktywną gest, nie jest to reaguje wystarczająco szybko
faktycznie działa z szybkim interaktywnym gestem, o ile zostawiam palec wystarczająco długo. Na przykład, jeśli bardzo szybko przesuwalę ponad (powiedzmy) 1 cm, jest w porządku. To nie w porządku, gdybym pan bardzo szybko na małej powierzchni (powiedzmy znowu) mniej niż 1cm
potencjalnych kandydatów obejmują poglądy są animowane są zbyt skomplikowane (lub skomplikowane efekty jak cieniowanie)
Myślałem także o skomplikowanym widoku, ale nie sądzę, że mój widok jest naprawdę skomplikowany. Istnieje kilka przycisków i etykiet, niestandardowy UIControl
działający jak segmentowany segment, wykres (ładowany po pojawieniu się kontrolera) i ładowany jest plik xib wewnątrz kontrolki viewController.
Ok Właśnie stworzyliśmy project z klas minimum i obiektów w celu wywołania problemu. Aby go uruchomić, wystarczy wykonać szybkie i krótkie przesunięcie z prawej strony na lewo.
Zauważyłem, że za pierwszym razem działa całkiem łatwo, ale jeśli przeciągasz kontroler widoku normalnie za pierwszym razem, to znacznie trudniej jest go wyzwolić (nawet niemożliwe?). Podczas gdy w moim pełnym projekcie, to naprawdę nie ma znaczenia.
@Rob Próbowałem wszystkiego, ale to nie rozwiązało problemu. Jedynym momentem, w którym było OK, było to, że ToViewController był prawie pusty. Zaktualizowałem pytanie linkiem do minimalnego projektu, który powoduje problem. Dzięki za pomoc. – Nico
@Rob czy wypróbowałeś to na symulatorze lub na urządzeniu? Dla twojej informacji, na symulatorze nie mogę go odtworzyć w ogóle, nawet przy pełnym projekcie. Używam mojego iPhone'a 6 i ostatniej wersji iOS – Nico
ok dzięki jeszcze raz za poświęcony czas. Zauważam też coś innego. Jeśli spróbujesz zaprezentować toViewController i anulować przejście, obiekt nie zostanie dezinicjowany. Zostanie deinicjalizowany po następnym wyświetleniu dowolnego kontrolera widoku (nawet jeśli wywołasz ten sam kontroler widoku). – Nico