1

ナビゲーションコントローラでどのようにこの効果を実現しますか?湾曲したエッジと透明なステータスバーを含む短いUINavigationBar

UINavigationControllerにVCが1つしか埋め込まれておらず、別のVCでモーダルに表示されています。これまでのところ良くなっていますが、ナビゲーションバーが短く、以下のような外観を実現したい場合は、エッジが湾曲し、ステータスバーの部分が透明になり、ViewControllerのステータスバーが表示されます。

enter image description here

これは私がこれまでのストーリーボードで、これまで持っているものです。

enter image description here

これまでのところ私はUINavigationControllerをサブクラス化することにより、ナビゲーションバーのための丸いエッジを達成することができました。しかし、上からナビバーを短くする方法はわかりません:

class ComposeNavigController: UINavigationController { 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 

     self.definesPresentationContext = true 
     self.providesPresentationContextTransitionStyle = true 
     self.modalPresentationCapturesStatusBarAppearance = false 
     self.modalPresentationStyle = .overFullScreen 


    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
      view.clipsToBounds = true 
      view.layer.cornerRadius = 16.0 
      view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] 
      view.layer.shadowOffset = .zero 
      view.layer.shadowColor = UIColor.black.cgColor 
      view.layer.shadowRadius = 16.0 
      view.layer.shadowOpacity = 0.5 
    } 

    override func viewDidLayoutSubviews() { 
     super.viewDidLayoutSubviews() 

     view.layer.shadowPath = UIBezierPath(rect: view.bounds).cgPath 
    } 

} 

これはうまく動作し、エッジをカーブします。

enter image description here

答えて

2

さてさて、ので、ここで私は私の質問でUINavigationControllerサブクラスに加えて、しなければならなかったものです。私が望むことを達成するためには、UIViewControllerAnimatedTransitioning代理人を使用しなければなりませんでした。

サブクラスNSObjectの2つのクラスを作成し、上記のプロトコルに準拠しています。

まず一つはUIViewControllerTransitioningDelegateプロトコルに準拠するために必要なこれのViewControllerを提示するだろうビューコントローラから次にdismiss transition-

import UIKit 

class ComposeDismissTransitionController: NSObject, UIViewControllerAnimatedTransitioning { 

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

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 

     let fromViewController = transitionContext.viewController(forKey: .from)! 
     let toViewController = transitionContext.viewController(forKey: .to)! 

     let screenBounds = UIScreen.main.bounds 
     var finalFrame = fromViewController.view.frame 
     finalFrame.origin.y = screenBounds.size.height 

     UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0.0, options: .curveEaseIn, 
         animations: { 
         fromViewController.view.frame = finalFrame 
         toViewController.view.alpha = 1.0 
     }) { (finished) in 
      fromViewController.view.removeFromSuperview() 
      transitionContext.completeTransition(finished) 
     } 
    } 
} 

ためpresent transition-

import UIKit 

class ComposePresentTransitionController: NSObject, UIViewControllerAnimatedTransitioning { 

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

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 

     let fromViewController = transitionContext.viewController(forKey: .from)! 
     let toViewController = transitionContext.viewController(forKey: .to)! 
     let containerView = transitionContext.containerView 

     let screenBounds = UIScreen.main.bounds 
     let topOffset: CGFloat = UIApplication.shared.statusBarFrame.height 

     var finalFrame = transitionContext.finalFrame(for: toViewController) 
     finalFrame.origin.y += topOffset 
     finalFrame.size.height -= topOffset 

     toViewController.view.frame = CGRect(x: 0.0, y: screenBounds.size.height, 
              width: finalFrame.size.width, 
              height: finalFrame.size.height) 
     containerView.addSubview(toViewController.view) 

     UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 1.0, options: .curveEaseOut, animations: { 
      toViewController.view.frame = finalFrame 
      fromViewController.view.alpha = 0.3 
     }) { (finished) in 
      transitionContext.completeTransition(finished) 
     } 

     UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0.0, options: .curveEaseOut, 
         animations: { 

     }) { (finished) in 

     } 
    } 
} 

第二に、のためのものであり、 animationController:forPresentedanimationController:forDismissedのような方法を実装します。

あなたは私のようなセグエ嫌いであれば、あなたは IBActionからこれを行うことができ、

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     super.prepare(for: segue, sender: sender) 
     segue.destination.transitioningDelegate = self 
    } 

- それが終わった後は210

extension PresentingVC: UIViewControllerTransitioningDelegate { 

    func animationController(forPresented presented: UIViewController, 
          presenting: UIViewController, 
          source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return ComposePresentTransitionController() 
    } 

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return ComposeDismissTransitionController() 
    } 
} 

は、PresentingVCprepareForSegueで行われていたUIViewControllerTransitioningDelegateからselfを設定するために必要なコード内のすべてのボタンも。これだけ

@IBAction func composeTap(_ sender: Any) { 
     let composeVC = self.storyboard?.instantiateViewController(withIdentifier: "compose") as! ComposeNavigController //this should be the navigation controller itself not the embedded viewcontroller 
     composeVC.transitioningDelegate = self 
     self.present(composeVC, animated: true, completion: nil) 
    } 

ボタンがモーダルメール作成画面を提示するためにタップされた時はいつでも...今、それはモーダルで、私は望ましい効果でアニメーション化するでしょう。ちょうど楽しみのためにちょうど楽しみをちょうど加えた効果を加えました:)

enter image description here

関連する問題