【发布时间】:2019-06-09 22:22:14
【问题描述】:
我试图在点击按钮时以模态方式呈现一个视图,该视图首先与按钮具有相同的框架,然后扩展为全屏,所有这些都使用UIViewControllerTransitioningDelegate。
这是我的代码:
可扩展基础
class ExpandableBase: UIViewController {
var senderFrame: CGRect = .zero
@IBOutlet weak var fullScreenPopupView: UIView?
@IBAction func dismiss() {
self.dismiss(animated: true, completion: nil)
}
}
过渡委托扩展
extension ExpandableBase: UIViewControllerTransitioningDelegate {
public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return ExpandableBasePresenter()
}
public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return ExpandableBaseDismisser()
}
}
private final class ExpandableBasePresenter: NSObject, UIViewControllerAnimatedTransitioning {
public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.8
}
public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let toViewController: ExpandableBase = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) as! ExpandableBase
let duration = self.transitionDuration(using: transitionContext)
let containerView = transitionContext.containerView
toViewController.view.frame = containerView.frame
containerView.addSubview(toViewController.view)
let finishFrame = toViewController.fullScreenPopupView?.frame
toViewController.fullScreenPopupView?.frame = toViewController.senderFrame
UIView.animate(withDuration: duration, delay: 0.3, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, options: .layoutSubviews, animations: {
toViewController.fullScreenPopupView?.frame = finishFrame!
}) { result in
transitionContext.completeTransition(result)
}
}
}
private final class ExpandableBaseDismisser: NSObject, UIViewControllerAnimatedTransitioning {
public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.4
}
public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let fromViewController: ExpandableBase = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) as! ExpandableBase
let duration = self.transitionDuration(using: transitionContext)
UIView.animate(withDuration: duration, delay: 0.1, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, options: .layoutSubviews, animations: {
fromViewController.fullScreenPopupView?.frame = fromViewController.senderFrame
}) { result in
transitionContext.completeTransition(result)
}
}
}
使用它的简单视图,显示标签和关闭按钮:
final class ExpandableSimpleView: ExpandableBase {
init(from initialFrame: CGRect) {
super.init(nibName: "ExpandableSimpleView", bundle: .main)
self.senderFrame = initialFrame
self.transitioningDelegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("NOPE")
}
static func present(fromInitialFrame initialFrame: CGRect) {
let expandableSimpleView = ExpandableSimpleView(from: initialFrame)
expandableSimpleView.modalPresentationStyle = .overCurrentContext
AppDelegateTopMostViewController.present(expandableSimpleView, animated: true, completion: nil)
//AppDelegateTopMostViewController is a global reference to the top-most view controller of the app
}
}
这里是对应的XIB:
以及我如何从父视图控制器呈现它:
@IBAction func openSimpleView(_ sender: UIButton) {
ExpandableSimpleView.present(fromInitialFrame: sender.frame)
}
这里有一些屏幕截图显示了这个视图是如何扩展的:
虽然视图扩展得很好,但标签并没有像应有的那样居中。我不明白为什么。
感谢您的帮助。
编辑:按照马特的回答,我对animateTransition 的演示者进行了以下更改。
toViewController.fullScreenPopupView!.transform =
toViewController.fullScreenPopupView!.transform.scaledBy(x: toViewController.senderFrame.width / toViewController.view.bounds.width, y: toViewController.senderFrame.height / toViewController.view.bounds.height)
UIView.animate(withDuration: duration, delay: 0, options: [.allowUserInteraction], animations: {
toViewController.fullScreenPopupView!.transform = .identity
}, completion: nil)
现在动画很好,但我面临另一个问题:视图中的按钮不再可点击。
【问题讨论】:
标签: ios autolayout uiviewanimationtransition