使用演示文稿(如动作iOS 13) [英] Use presentation like actions iOS 13

查看:73
本文介绍了使用演示文稿(如动作iOS 13)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想像标准应用程序Mail,Music和UIActivityViewController中那样实现控制器的表示.默认情况下,此控制器显示为一半,如果您滑动该控制器,它将完全打开.

I want to implement the presentation of controllers as in the standard applications Mail, Music and as in the UIActivityViewController. This controller shows on half by default and if you swipe, the controller will open completely.

我如何使用我的自定义控制器来实现此演示文稿?

How I can implement this presentation with my custom controller?

我在文档中找不到有关此演示文稿实现的参考.

I can’t find references to the implementation of such a presentation in the documentation.

屏幕截图:

推荐答案

请勿使用自定义的演示控制器,因为这样会丢失Apple提供的视觉效果和物理效果.

Do not use a custom presentation controller, because you would lose the visuals and physics provided by Apple.

正常显示,然后使用 viewDidLayoutSubviews 中的 systemLayoutSizeFitting 将框架调整为所需的最小尺寸.假设您的自定义控制器为 CustomController ,则将其替换为该子类即可.

Present normally, then use systemLayoutSizeFitting in viewDidLayoutSubviews to adjust the frame to the minimum required size. Assuming your custom controller is CustomController, replace it with this subclass and you are done.

import UIKit

final class ResizedViewController: CustomController {

    private let cornerRadius: CGFloat = 22
    private var containerView: UIView? { view.superview }
    private var presentedView: UIView? { view }

    private lazy var tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(resign))

    override func viewDidLoad() {

        super.viewDidLoad()
        tapRecognizer.cancelsTouchesInView = true
        view.layer.cornerRadius = cornerRadius
        view.layer.cornerCurve = .continuous
    }

    override func viewDidAppear(_ animated: Bool) {

        super.viewDidAppear(animated)
        containerView?.addGestureRecognizer(tapRecognizer)
    }

    override func viewWillDisappear(_ animated: Bool) {

        super.viewWillDisappear(animated)
        if let recognizer = containerView?.gestureRecognizers?.first(where: { $0 == tapRecognizer }) {
            containerView?.removeGestureRecognizer(recognizer)
        }
    }

    override func viewDidLayoutSubviews() {

        super.viewDidLayoutSubviews()
        view.frame = frameOfPresentedViewInContainerView
    }

    private var frameOfPresentedViewInContainerView: CGRect {
        guard let containerView = containerView else {
            return CGRect.zero
        }
        guard let presentedView = presentedView else {
            return CGRect.zero
        }
        let safeBounds = containerView.bounds.inset(by: containerView.safeAreaInsets)
        let newSize = CGSize(
            width: safeBounds.width,
            height: UIView.layoutFittingCompressedSize.height
        )
        let newHeight = view.safeAreaInsets.bottom +
            presentedView.systemLayoutSizeFitting(
                newSize,
                withHorizontalFittingPriority: .required,
                verticalFittingPriority: .defaultLow
            ).height
        return CGRect(
            x: 0,
            y: containerView.frame.height - newHeight,
            width: safeBounds.width,
            height: newHeight
        )
    }

    @objc
    private func resign() {

        dismiss(animated: true, completion: nil)
    }
}

需要使用超级视图上的敲击识别器来消除控制器在外部的敲击.更改框架后,Apple的 cornerRadius 丢失了,所以我再次进行设置.

The tap recognizer on the superview is needed to dismiss the controller tapping outside. The cornerRadius from Apple is lost after altering the frame so I set it again.

这篇关于使用演示文稿(如动作iOS 13)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆