swift 내부에内容视图控制器를过渡효과를주어바꿀수있는根视图控制器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift 내부에内容视图控制器를过渡효과를주어바꿀수있는根视图控制器相关的知识,希望对你有一定的参考价值。
//
// RootViewController.swift
// FiverPOS
//
// Created by ljw on 2016. 10. 6..
// Copyright © 2016년 Vovios Networks Inc. All rights reserved.
//
import UIKit
class RootViewControllerSegue: UIStoryboardSegue {
override func perform() {
guard let rootVC = source as? RootViewController else {
fatalError("RootViewControllerSegue's source should be RootViewController")
}
rootVC.addRootContentViewController(destination, animated: false)
}
}
/// 화면 전환을 담당하는 윈도우의 Root View Controller
class RootViewController: ViewController {
var rootContainer: UIView = UIView(frame: UIScreen.main.bounds)
var rootViewController: UIViewController? {
return childViewControllers.last
}
override func loadView() {
super.loadView()
let container = rootContainer
container.backgroundColor = .clear
view.insertSubview(container, at: 0)
container.translatesAutoresizingMaskIntoConstraints = false
container.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
container.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true
container.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
container.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
layoutStatusBar()
}
init(rootViewController: UIViewController? = nil) {
super.init(nibName: nil, bundle: nil)
if let vc = rootViewController {
addRootContentViewController(vc, animated: false)
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
performSegue(withIdentifier: "root", sender: nil)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
}
/// Transitioning Code
extension RootViewController {
/// Transition animation duration
static var transitionDuration: TimeInterval {
return 0.5
}
/// child view controller 간에 전환을 시키는 메소드
func transition(to viewController: UIViewController?, animated: Bool, completion: (() -> Void)? = nil) {
let rootViewController = self.rootViewController
switch (rootViewController, viewController) {
case (nil, nil): return
case (let previousRootViewController?, nil):
removeRootContentViewController(previousRootViewController, animated: animated, completion: completion)
case (nil, let newRootViewController?):
addRootContentViewController(newRootViewController, animated: animated, completion: completion)
case (let previous?, let new?):
transitionRootContent(from: previous, to: new, animated: animated, completion: completion)
}
}
/// 자식 뷰컨트롤러 간 전환
func transitionRootContent(from fromViewController: UIViewController, to toViewController: UIViewController, animated: Bool, completion: (() -> Void)? = nil) {
guard childViewControllers.contains(fromViewController) else {
fatalError("fromViewController should belong to root view controller's childViewControllers")
}
// prepare view controller's containment hierarchy
fromViewController.willMove(toParentViewController: nil)
addChildViewController(toViewController)
// prepare new view hierarchy layout
toViewController.view.frame = rootContainer.bounds
if animated {
// prepare animation
toViewController.view.alpha = 0
// perform animation and apply new view hierarchy
transition(from: fromViewController,
to: toViewController,
duration: RootViewController.transitionDuration,
options: [],
animations: {
// UIView.setAnimationsEnabled(false)
// toViewController.view.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
// UIView.setAnimationsEnabled(true)
//
// toViewController.view.transform = CGAffineTransform.identity
toViewController.view.alpha = 1
}) { (finished) in
// complete view controller's containment hierarchy
fromViewController.removeFromParentViewController()
toViewController.didMove(toParentViewController: self)
toViewController.view.clipsToBounds = true
toViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
toViewController.view.contentScaleFactor = UIScreen.main.scale
completion?()
}
} else {
// apply new view hierarchy
fromViewController.view.superview?.insertSubview(toViewController.view, aboveSubview: fromViewController.view)
fromViewController.view.removeFromSuperview()
// complete view controller's containment hierarchy
fromViewController.removeFromParentViewController()
toViewController.didMove(toParentViewController: self)
toViewController.view.clipsToBounds = true
toViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
toViewController.view.contentScaleFactor = UIScreen.main.scale
completion?()
}
}
/// 자식 뷰 컨트롤러 추가
func addRootContentViewController(_ viewController: UIViewController, animated: Bool, completion: (() -> Void)? = nil) {
// prepare view controller's containment hierarchy
addChildViewController(viewController)
// prepare new view hierarchy layout
viewController.view.frame = rootContainer.bounds
if animated {
// prepare animation
viewController.view.alpha = 0
// apply new view hierarchy
rootContainer.addSubview(viewController.view)
// perform animation
UIView.animate(withDuration: RootViewController.transitionDuration,
animations: {
viewController.view.alpha = 1.0
}) { (finished) in
// complete view controller's containment hierarchy
viewController.didMove(toParentViewController: self)
viewController.view.clipsToBounds = true
viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
viewController.view.contentScaleFactor = UIScreen.main.scale
completion?()
}
} else {
// apply new view hierarchy
rootContainer.addSubview(viewController.view)
// complete view controller's containment hierarchy
viewController.didMove(toParentViewController: self)
viewController.view.clipsToBounds = true
viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
viewController.view.contentScaleFactor = UIScreen.main.scale
completion?()
}
}
/// 자식 뷰컨트롤러 제거
func removeRootContentViewController(_ viewController: UIViewController, animated: Bool, completion: (() -> Void)? = nil) {
guard childViewControllers.contains(viewController) else {
fatalError("viewController to remove should belong to root view controller's childViewControllers")
}
// prepare view controller's containment hierarchy
viewController.willMove(toParentViewController: nil)
if animated {
// perform animation
UIView.animate(withDuration: RootViewController.transitionDuration,
animations: {
viewController.view.alpha = 0
},
completion: { (finished) in
// apply new view hierarchy
viewController.view.removeFromSuperview()
viewController.view.alpha = 1
// complete view controller's containment hierarchy
viewController.removeFromParentViewController()
completion?()
})
} else {
// apply new view hierarchy
viewController.view.removeFromSuperview()
// complete view controller's containment hierarchy
viewController.removeFromParentViewController()
completion?()
}
}
}
extension RootViewController {
private struct AssociatedKey {
static var statusBarHidden = "RootViewController.statusBarHidden"
static var statusBarLayer = "RootViewController.statusBarLayer"
}
fileprivate var statusBarLayer: CALayer {
var layer = objc_getAssociatedObject(self, &AssociatedKey.statusBarLayer) as? CALayer
if layer == nil {
layer = CALayer()
layer?.zPosition = 3000
layer?.backgroundColor = UIColor(white: 0.0, alpha: 0.12).cgColor
objc_setAssociatedObject(self, &AssociatedKey.statusBarLayer, layer, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
return layer!
}
@IBInspectable var statusBarHidden: Bool {
get {
if let hidden = objc_getAssociatedObject(self, &AssociatedKey.statusBarHidden) as? Bool {
return hidden
} else {
return true
}
}
set {
objc_setAssociatedObject(self, &AssociatedKey.statusBarHidden, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
fileprivate func layoutStatusBar() {
let layer = statusBarLayer
if statusBarHidden == false {
let statusBarFrame = view.convert(UIApplication.shared.statusBarFrame, from: UIApplication.shared.keyWindow)
layer.frame = statusBarFrame
if layer.superlayer == nil {
view.layer.addSublayer(layer)
}
} else {
if layer.superlayer != nil {
layer.removeFromSuperlayer()
}
}
}
}
以上是关于swift 내부에内容视图控制器를过渡효과를주어바꿀수있는根视图控制器的主要内容,如果未能解决你的问题,请参考以下文章