2015-01-17 2 views
4

У меня есть проект Swift, изучающий API погоды, а также попытка получить лучшую ручку на AnimatedTransitions. У меня есть UITableView с использованием пользовательского UITableViewCell с изображениями и текстом. Нажатие ячейки в таблицеView переходит к новому UIViewController как Show (push), причем все это встроено в UINavigationController.iOS Swift: UIViewControllerAnimatedTransitioning конечный кадр в неправильном положении

При вызове перехода изображение из ячейки должно переместиться в конечное местоположение UIImageView на целевом диспетчере viewController. Тем не менее, то, что он делает, проходит мимо этой точки на другую сторону экрана до того, как переход завершается, и вид изменяется, заставляя изображение снова привязываться к центру представления.

screenshots

Я прочитал много учебников, пытаясь исправить это и прочитал много StackOverflow, но не смогли понять его. Может кто-нибудь указать мне, что я пропустил, пожалуйста? Я схожу с ума.

переход, который вызывает переход в оригинале ViewController:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    self.performSegueWithIdentifier("SHOW_DETAIL", sender: self) 
} 

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if segue.identifier == "SHOW_DETAIL" { 
    let detailVC = segue.destinationViewController as DetailViewController 
    let indexPathForForecast = self.tableView.indexPathForSelectedRow() as NSIndexPath! 
    let detailForecast = self.forecasts?[indexPathForForecast.row] 
    let cell = self.tableView.cellForRowAtIndexPath(indexPathForForecast) as WeatherCell 
    let image = cell.forecastImage.image 
    detailVC.forecastForDetail = detailForecast 
    detailVC.forecastDetailImage = image 
    } 
} 

func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
    if fromVC == self && toVC.isKindOfClass(DetailViewController) { 
    let transitionVC = AnimateToDetailVCController() 
    return transitionVC 
    } else { 
    return nil 
    } 
} 

А вот animateTransition код от объекта UIViewControllerAnimatedTransitioning (EDIT: Код решения отредактирован в блоке кода, благодаря @jrturton!)

func animateTransition(transitionContext: UIViewControllerContextTransitioning) { 
    let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as ViewController 
    let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as DetailViewController 

    let containerView = transitionContext.containerView() 
    let duration = self.transitionDuration(transitionContext) 

    let selectedRow = fromViewController.tableView.indexPathForSelectedRow() 
    let cell = fromViewController.tableView.cellForRowAtIndexPath(selectedRow!) as WeatherCell 
    let weatherSnapshot = cell.forecastImage.snapshotViewAfterScreenUpdates(false) 
    weatherSnapshot.frame = containerView.convertRect(cell.forecastImage.frame, fromView: fromViewController.tableView.cellForRowAtIndexPath(selectedRow!)?.superview) 
    cell.forecastImage.hidden = true 

    toViewController.view.frame = transitionContext.finalFrameForViewController(toViewController) 
    toViewController.view.alpha = 0 
    toViewController.detailImageView.hidden = true 

    containerView.addSubview(toViewController.view) 
    containerView.addSubview(weatherSnapshot) 

    var toFrame = toViewController.locationIs 

    UIView.animateWithDuration(duration, animations: {() -> Void in 
    // EDIT: This solved the issue, thanks JRTurton! 
    toViewController.view.setNeedsLayout() // Solution: This is where it was needed 
    toViewController.view.layoutIfNeeded() // Solution: This is where it was needed 

    toViewController.view.alpha = 1.0 
    var endRect = containerView.convertRect(toViewController.detailImageView.frame, fromView: toViewController.view) 
    weatherSnapshot.frame = endRect 

    }) { (finished) -> Void in 
    toViewController.detailImageView.hidden = false 
    cell.forecastImage.hidden = false 
    weatherSnapshot.removeFromSuperview() 

    transitionContext.completeTransition(true) 
    } 

} 

ответ

15

Это трудно сказать, но вот мой предположение: вы используете классы размеров, проектирование в любой/любого размера, и изображение в вашем контроллере просмотра по-прежнему сосредоточено в отношении этого, когда вы получаете его фрейм для использования в своей анимации, делая его слишком далеко вправо. Как только переход завершен, происходит переход макета, и он исправляется.

Чтобы исправить, после того, как вы установите рамку для просмотра контроллера, заставить проход макета:

toViewController.view.setNeedsLayout() 
toViewController.view.layoutIfNeeded() 

Перед выполнением вышеуказанного изменения, вы можете сначала проверить, действительно ли это проблема, проверив вид изображения в перед анимацией.

+1

Отлично, большое спасибо @jrturton. Это было отлично. Я удивлен, что в каждом учебнике не упоминается, не люди ли используют автоматическую компоновку? Я должен был добавить его в блок анимации, или он все еще был неуместным, но это было легко и просто. Я отредактировал его в вопросе. –

+1

Мне нравится, когда мои догадки верны: D – jrturton

+0

Спасибо. Это работает. – honcheng

Смежные вопросы