视图是黑色的,当返回到导航控制器堆栈视图时,在实现自定义转换后
Posted
技术标签:
【中文标题】视图是黑色的,当返回到导航控制器堆栈视图时,在实现自定义转换后【英文标题】:View is black, when going back in the navigationcontrollers stack of views, after implementing custom transition 【发布时间】:2018-05-18 10:31:25 【问题描述】:我有一个包含元素列表的表格视图。在点击表格视图中的单元格时,我尝试实现到详细视图的缩放转换。 过渡按预期工作 - 但是当我按“返回”时,我被带到一个黑色视图。
我是使用自定义过渡的新手,所以也许我缺少一些东西 - 我只是不确定是什么。我按照这篇文章:https://blog.rocketinsights.com/how-to-create-a-navigation-transition-like-the-apple-news-app/ 进行了缩放转换,并将代码转换为 Swift 4。
这是我的 zoomtransition 类:
class ZoomTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning
private let duration: TimeInterval = 0.5
var operation: UINavigationControllerOperation = .push
var thumbnailFrame = CGRect.zero
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval
return duration
func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
let presenting = operation == .push
// Determine which is the master view and which is the detail view that we're navigating to and from. The container view will house the views for transition animation.
let containerView = transitionContext.containerView
guard let toView = transitionContext.view(forKey: UITransitionContextViewKey.to) else return
guard let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from) else return
let storyFeedView = presenting ? fromView : toView
let storyDetailView = presenting ? toView : fromView
// Determine the starting frame of the detail view for the animation. When we're presenting, the detail view will grow out of the thumbnail frame. When we're dismissing, the detail view will shrink back into that same thumbnail frame.
var initialFrame = presenting ? thumbnailFrame : storyDetailView.frame
let finalFrame = presenting ? storyDetailView.frame : thumbnailFrame
// Resize the detail view to fit within the thumbnail's frame at the beginning of the push animation and at the end of the pop animation while maintaining it's inherent aspect ratio.
let initialFrameAspectRatio = initialFrame.width / initialFrame.height
let storyDetailAspectRatio = storyDetailView.frame.width / storyDetailView.frame.height
if initialFrameAspectRatio > storyDetailAspectRatio
initialFrame.size = CGSize(width: initialFrame.height * storyDetailAspectRatio, height: initialFrame.height)
else
initialFrame.size = CGSize(width: initialFrame.width, height: initialFrame.width / storyDetailAspectRatio)
let finalFrameAspectRatio = finalFrame.width / finalFrame.height
var resizedFinalFrame = finalFrame
if finalFrameAspectRatio > storyDetailAspectRatio
resizedFinalFrame.size = CGSize(width: finalFrame.height * storyDetailAspectRatio, height: finalFrame.height)
else
resizedFinalFrame.size = CGSize(width: finalFrame.width, height: finalFrame.width / storyDetailAspectRatio)
// Determine how much the detail view needs to grow or shrink.
let scaleFactor = resizedFinalFrame.width / initialFrame.width
let growScaleFactor = presenting ? scaleFactor: 1/scaleFactor
let shrinkScaleFactor = 1/growScaleFactor
if presenting
// Shrink the detail view for the initial frame. The detail view will be scaled to CGAffineTransformIdentity below.
storyDetailView.transform = CGAffineTransform(scaleX: shrinkScaleFactor, y: shrinkScaleFactor)
storyDetailView.center = CGPoint(x: thumbnailFrame.midX, y: thumbnailFrame.midY)
storyDetailView.clipsToBounds = true
// Set the initial state of the alpha for the master and detail views so that we can fade them in and out during the animation.
storyDetailView.alpha = presenting ? 0 : 1
storyFeedView.alpha = presenting ? 1 : 0
// Add the view that we're transitioning to to the container view that houses the animation.
containerView.addSubview(toView)
containerView.bringSubview(toFront: storyDetailView)
// Animate the transition.
UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 1.0, options: [.curveEaseInOut], animations:
// Fade the master and detail views in and out.
storyDetailView.alpha = presenting ? 1 : 0
storyFeedView.alpha = presenting ? 0 : 1
if presenting
// Scale the master view in parallel with the detail view (which will grow to its inherent size). The translation gives the appearance that the anchor point for the zoom is the center of the thumbnail frame.
let scale = CGAffineTransform(scaleX: growScaleFactor, y: growScaleFactor)
let translate = storyFeedView.transform.translatedBy(x: storyFeedView.frame.midX - self.thumbnailFrame.midX, y: storyFeedView.frame.midY - self.thumbnailFrame.midY)
storyFeedView.transform = translate.concatenating(scale)
storyDetailView.transform = .identity
else
// Return the master view to its inherent size and position and shrink the detail view.
storyFeedView.transform = .identity
storyDetailView.transform = CGAffineTransform(scaleX: shrinkScaleFactor, y: shrinkScaleFactor)
// Move the detail view to the final frame position.
storyDetailView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
) finished in
transitionContext.completeTransition(finished)
在我的主视图控制器中,我使用以下代码实现了 UINavigationControllerDelegate:
extension SearchVC: UINavigationControllerDelegate
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
if operation == .push
//Pass the thumbnail frame to the transition animator.
guard let transitionThumbnail = transitionThumbnail, let transitionThumbnailSuperview = transitionThumbnail.superview else return nil
thumbnailZoomTransitionAnimator = ZoomTransitionAnimator()
thumbnailZoomTransitionAnimator?.thumbnailFrame = transitionThumbnailSuperview.convert(transitionThumbnail.frame, to: nil)
thumbnailZoomTransitionAnimator?.operation = operation
return thumbnailZoomTransitionAnimator
最后,当点击表格视图中的一个单元格时,这是我的代码:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
let cell = tableView.cellForRow(at: indexPath as IndexPath) as? MovieTableViewCell
transitionThumbnail = cell?.movieImageView
self.performSegue(withIdentifier: "searchToDetails", sender: indexPath.row)
我的 segue 以“prepare for segue”方法将数据发送到详细视图。
谁能解释/帮助我出了什么问题? :-) 只有在返回时才提到,视图变黑了。
【问题讨论】:
您的问题解决了吗?我有完全一样的...... 我找到了解决方案,代码在这里:***.com/questions/51617051/… 【参考方案1】:我认为您需要在动画完成后设置呈现才能处理切换。
finished in
transitionContext.completeTransition(finished)
presenting = !presenting
【讨论】:
那没有任何区别 :/ 但我想,问题是,当我回去的时候,主视图被缩小了..所以它实际上变得越来越小时间我去细节和回来..我只是不知道在哪里编辑主视图的收缩:/以上是关于视图是黑色的,当返回到导航控制器堆栈视图时,在实现自定义转换后的主要内容,如果未能解决你的问题,请参考以下文章
将带有可见导航栏的视图控制器弹出到带有隐藏导航栏的视图控制器时,带有 interactivePopGestureRecognizer 的黑色区域