iOS - Swift:在UITableView中展开用户个人资料图片

时间:2018-04-03 10:45:07

标签: ios swift uitableview popup expand

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

enter image description here

////////////////
到这个 ///////////////

enter image description here     在这里输入代码

它有效,但问题是动画以某种方式从屏幕的角落开始,而不是从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
}

我无法获得与整个屏幕相关的正确帧,以便我的动画从小区的个人资料图片开始。

欢迎任何建议

2 个答案:

答案 0 :(得分:0)

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

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

let rect = tableView.rectForRow(at: indexPath)

如果你需要相对于另一个视图的rect,你可以使用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)

答案 1 :(得分:0)

以防万一其他人正在寻找相同的动画,这里有过渡类:
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)
    })
  }
}  

TransitioningDelegate

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提供的上述代码将为您提供相同的动画。