如何在iOS 7自定义转换的顶部呈现半模态视图控制器

rpppsulh  于 2022-12-30  发布在  iOS
关注(0)|答案(2)|浏览(94)

如何在主视图控制器的顶部显示一个"半视图"控制器?
要求:- 提供在主视图控制器顶部滑动的第二个视图控制器。-第二个视图控制器应仅显示主视图控制器的一半以上-主视图控制器应在第二个视图控制器后面保持可见(透明背景,下方不显示黑色)-第二个视图控制器应使用类似于模态垂直覆盖的动画进行动画处理,或iOS 7自定义转换-当第二个视图控制器处于活动状态时,用户仍可与主视图控制器上的按钮交互(即第二个视图控制器不覆盖整个主视图控制器)r-第二个视图控制器具有其自身的复杂逻辑(不能是简单的视图)-故事板、Segues、仅iOS 7-仅iPhone,而不是iPad。
我试过模态视图控制器,但这不允许与主视图控制器交互。有人能提供一个如何用iOS7自定义转换或其他方法做到这一点的例子吗?

yrdbyhpb

yrdbyhpb1#

一种方法是将“半模态”控制器添加为子视图控制器,并将其视图动画化到适当的位置。在本例中,我在故事板中创建了“半模态”控制器,其框架为4英寸iPhone屏幕高度的一半。您可以使用更多动态方法来考虑不同的屏幕大小,但这应该可以让您开始使用。

@interface ViewController ()
@property (strong,nonatomic) UIViewController *modal;
@end

@implementation ViewController

- (IBAction)toggleHalfModal:(UIButton *)sender {
    if (self.childViewControllers.count == 0) {
        self.modal = [self.storyboard instantiateViewControllerWithIdentifier:@"HalfModal"];
        [self addChildViewController:self.modal];
        self.modal.view.frame = CGRectMake(0, 568, 320, 284);
        [self.view addSubview:self.modal.view];
        [UIView animateWithDuration:1 animations:^{
            self.modal.view.frame = CGRectMake(0, 284, 320, 284);;
        } completion:^(BOOL finished) {
            [self.modal didMoveToParentViewController:self];
        }];
    }else{
        [UIView animateWithDuration:1 animations:^{
            self.modal.view.frame = CGRectMake(0, 568, 320, 284);
        } completion:^(BOOL finished) {
            [self.modal.view removeFromSuperview];
            [self.modal removeFromParentViewController];
            self.modal = nil;
        }];
    }
}
guicsvcw

guicsvcw2#

在半屏中显示控制器的新方法是ios原生风格的控制器。sheetPresentationController,但这只适用于ios 15及更高版本,对于以前的版本,您需要设置。自定义modalPresentationStype
下面的代码片段可以帮助您实现这两个版本

controller.modalPresentationStyle = .pageSheet
    if #available(iOS 15.0, *) {

        if let sheet = controller.sheetPresentationController {
            sheet.detents = [.medium()]
        }
        
    } else {
        
        controller.modalPresentationStyle = .custom
        controller.transitioningDelegate = self
    }
    self.present(controller, animated: true, completion: nil)

// MARK:-UI视图控制器转换委托

extension CPPdfPreviewVC: UIViewControllerTransitioningDelegate {
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
    PresentationController(presentedViewController: presented, presenting: presenting)
    }
}

并添加给定的表示控制器

class PresentationController: UIPresentationController {

  let blurEffectView: UIVisualEffectView!
  var tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer()
  
  override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
      let blurEffect = UIBlurEffect(style: .dark)
      blurEffectView = UIVisualEffectView(effect: blurEffect)
      super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
      tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissController))
      blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
      self.blurEffectView.isUserInteractionEnabled = true
      self.blurEffectView.addGestureRecognizer(tapGestureRecognizer)
  }
  
  override var frameOfPresentedViewInContainerView: CGRect {
      CGRect(origin: CGPoint(x: 0, y: self.containerView!.frame.height * 0.4),
             size: CGSize(width: self.containerView!.frame.width, height: self.containerView!.frame.height *
              0.6))
  }

  override func presentationTransitionWillBegin() {
      self.blurEffectView.alpha = 0
      self.containerView?.addSubview(blurEffectView)
      self.presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) in
          self.blurEffectView.alpha = 0.7
      }, completion: { (UIViewControllerTransitionCoordinatorContext) in })
  }
  
  override func dismissalTransitionWillBegin() {
      self.presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) in
          self.blurEffectView.alpha = 0
      }, completion: { (UIViewControllerTransitionCoordinatorContext) in
          self.blurEffectView.removeFromSuperview()
      })
  }
  
  override func containerViewWillLayoutSubviews() {
      super.containerViewWillLayoutSubviews()
    presentedView!.roundCorners([.topLeft, .topRight], radius: 22)
  }

  override func containerViewDidLayoutSubviews() {
      super.containerViewDidLayoutSubviews()
      presentedView?.frame = frameOfPresentedViewInContainerView
      blurEffectView.frame = containerView!.bounds
  }

  @objc func dismissController(){
      self.presentedViewController.dismiss(animated: true, completion: nil)
  }
}

extension UIView {
  func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
      let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners,
                              cornerRadii: CGSize(width: radius, height: radius))
      let mask = CAShapeLayer()
      mask.path = path.cgPath
      layer.mask = mask
  }
}

相关问题