iOS - Swift : 在UITableView中展开用户头像

iOS - Swift : Expand user profile picture in UITableView

我正在尝试从 UITableViewCell 获取动画(保存有关用户的信息,带有个人资料图片),方法是扩展用户的个人资料图片:

///////////////
对此
//////////////

在此处输入代码

它有效,但问题是动画以某种方式从屏幕的角落开始,而不是从 UITableViewCell 中的圆形图像开始。

func handlePictureTap(conversationTableCell: ConversationTableCell) {
    guard let cellIndexPath = self.conversationsTableView.indexPath(for: conversationTableCell) else { return }

    transitionDelegate.openingFrame = self.frameForCellAtIndexPath(cellIndexPath)

    let userProfileViewController = UserViewController(nibName: "UserViewController", bundle: nil)
    userProfileViewController.recentProfileProtocol = self
    userProfileViewController.transitioningDelegate = transitionDelegate
    userProfileViewController.modalPresentationStyle = .overCurrentContext
    userProfileViewController.userProfileName = conversationTableCell.conversationName.text!
    userProfileViewController.userProfileImage = conversationTableCell.conversationPicture.image

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

以及 frameForCellAtIndexPath 的函数。

func frameForCellAtIndexPath(_ indexPath: IndexPath) -> CGRect {
    let cell = self.conversationsTableView.cellForRow(at: indexPath) as! ConversationTableCell

    let profileImageFrame = cell.conversationPicture.frame

    return profileImageFrame
}

我无法为它获取与整个屏幕相关的正确帧,以便我的动画从单元格的个人资料图片开始。

欢迎提出任何建议

您正在从相对于 table 视图单元格坐标系的图像帧开始动画,它位于左上角。

要确定单元格相对于 table 视图的当前位置,您可以使用如下内容:

let rect = tableView.rectForRow(at: indexPath)

如果您需要相对于另一个视图的矩形,您可以使用 UIViews

convert(_ rect: NSRect, from view: NSView?) -> NSRect

更新

假设您需要屏幕坐标中的 openingRect,要将其应用于您的特定情况,您可以执行类似以下操作:

let cellOrigin = tableView.rectForRow(at: indexPath).origin

let rectRelativeToTable = CGRect(x: imageFrame.origin.x + cellOrigin.x,
                                 y: imageFrame.origin.y + cellOrigin.y,
                                 width: imageFrame.size.width,
                                 height: imageFrame.size.height)

let openingRect = tableView.convert(rectRelativeToTable, to: nil)

以防万一其他人正在寻找相同的动画,这里是过渡 类:
DismissalAnimator

import UIKit

class DismissalAnimator: NSObject, UIViewControllerAnimatedTransitioning {
var openingFrame: CGRect?


func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
    return 0.6
}


func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
    let containerView = transitionContext.containerView

    let animationDuration = self .transitionDuration(using: transitionContext)

    let snapshotView = fromViewController.view.snapshotView(afterScreenUpdates: true)
    containerView.addSubview(snapshotView!)

    fromViewController.view.alpha = 0.0

    UIView.animate(
        withDuration: animationDuration,
        animations: { () -> Void in
            snapshotView!.frame = self.openingFrame!
            snapshotView!.alpha = 0.0
    },
        completion: { (finished) -> Void in
            snapshotView!.removeFromSuperview()

            fromViewController.view.removeFromSuperview()

            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    })
  }  

} 

PresentationAnimator

import UIKit

class PresentationAnimator: NSObject, UIViewControllerAnimatedTransitioning {
var openingFrame: CGRect?


func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
    return 0.6
}


func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
    let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
    let containerView = transitionContext.containerView

    let animationDuration = self.transitionDuration(using: transitionContext)

    containerView.addSubview(toViewController.view)

    let snapshotView = toViewController.view.snapshotView(afterScreenUpdates: true)
    snapshotView!.frame = openingFrame!

    toViewController.view.alpha = 0.0
    snapshotView!.alpha = 0

    containerView.addSubview(snapshotView!)

    UIView.animate(
        withDuration: animationDuration,
        delay: 0.0,
        usingSpringWithDamping: 2.0,
        initialSpringVelocity: 5.0,
        options: UIViewAnimationOptions.curveEaseOut,
        animations: { () -> Void in
            snapshotView!.frame = fromViewController.view.frame
            snapshotView!.alpha = 1
    },
        completion: { (finished) -> Void in
            snapshotView!.removeFromSuperview()

            toViewController.view.alpha = 1.0

            transitionContext.completeTransition(finished)
    })
  }
}  

过渡委托

import UIKit

class TransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
var openingFrame: CGRect?


func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    let presentationAnimator = PresentationAnimator()
    presentationAnimator.openingFrame = openingFrame

    return presentationAnimator
}


func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    let dismissAnimator = DismissalAnimator()
    dismissAnimator.openingFrame = openingFrame!

    return dismissAnimator
   }
}
  • @Stephan Schlecht 提供的上述代码将为您提供相同的动画。