首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PHPickerViewController上推送视图控制器

在PHPickerViewController上推送视图控制器
EN

Stack Overflow用户
提问于 2021-01-14 16:34:18
回答 1查看 666关注 0票数 0

这有可能将vc推到PHPickerViewController之上吗?

我试着这样做却没有运气:

代码语言:javascript
复制
var configuration = PHPickerConfiguration()
configuration.filter = .any(of: [.images, .livePhotos])
photoPickerController = PHPickerViewController(configuration: configuration)
photoPickerController.delegate = self
present(self.photoPickerController, animated: true)

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
  //Push segue
  performSegue(withIdentifier: "showAddPost", sender: self)
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-06 01:14:08

更新-使用CocoaPods

我创建了一个简单的pod PhotoCropController,其中包括一个将从PHPickerViewControllerDelegate中呈现的基本的裁剪控制器。它提供了转换,以推送到一个模式显示的控制器,并弹出或解散。作物视图的纵横比也可以编辑。要使用视图控制器,请将您的视图控制器与PhotoCropDelegate协议相结合,并显示来自PHPickerViewControllerDelegate的PhotoCropController。实现如下所示:

代码语言:javascript
复制
extension ViewController: PHPickerViewControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, PhotoCropDelegate {
    
    func browsePhotoLibrary() {
        if #available(iOS 14, *) {
            var config = PHPickerConfiguration()
            config.filter = PHPickerFilter.images
            config.selectionLimit = 1
            config.preferredAssetRepresentationMode = .compatible
            let picker = PHPickerViewController(configuration: config)
            picker.delegate = self
            let nav = UINavigationController(rootViewController: picker)
            nav.setNavigationBarHidden(true, animated: false)
            nav.setToolbarHidden(true, animated: true)
            present(nav, animated: true)            } else {
            let picker = UIImagePickerController()
            picker.delegate = self
            picker.allowsEditing = true
            present(picker, animated: true)
        }
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let edited = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
            image = edited
        } else if let selected = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            image = selected
        }
        presentedViewController?.dismiss(animated: true)
    }
    
    @available(iOS 14, *)
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        if let provider = results.last?.itemProvider,
           provider.canLoadObject(ofClass: UIImage.self) {
            provider.loadObject(ofClass: UIImage.self) { [weak self] result, error in
                if let image = result as? UIImage {
                    DispatchQueue.main.async { self?.select(image: image) }
                } else if let error = error {
                    NSLog("Error picking image: %@", error.localizedDescription)
                    DispatchQueue.main.async { picker.dismiss(animated: true) }
                }
            }
        } else { DispatchQueue.main.async { picker.dismiss(animated: true) } }
    }
    
    func select(image: UIImage) {
        let destinationSize = AVMakeRect(aspectRatio: image.size, insideRect: view.frame).integral.size
        //Best Performance
        let resizedImage = UIGraphicsImageRenderer(size: destinationSize).image { (context) in
            image.draw(in: CGRect(origin: .zero, size: destinationSize))
        }
        let cropController = PhotoCropController()
        cropController.delegate = self
        cropController.image = resizedImage
        presentedViewController?.present(cropController, animated: true)
    }
    
    @objc func cropViewDidCrop(image: UIImage?) {
        self.image = image
        presentedViewController?.dismiss(animated: true) { [weak self] in
            self?.presentedViewController?.dismiss(animated: true)
        }
    }
}

在PHPickerViewController前面以模式方式呈现另一个控制器:

视图控制器的presentedViewController属性将是您的photoPickerController,因此您可以在它前面显示另一个控制器,如下所示:

代码语言:javascript
复制
present(photoPickerController, animated: true)
presentedViewController?.present(yourViewController, animated: true)

如果退出presentedViewController,您将需要调用两次,一次是为了解散yourViewController,另一次是为了解散photoPickerController,如果它们都显示出来的话:

代码语言:javascript
复制
presentedViewController?.dismiss(animated: true)
presentedViewController?.dismiss(animated: true)

在导航堆栈上推送自定义控制器

要创建推送到PHPickerViewController堆栈的外观,可以使用自定义的UIPresentationController和UIViewControllerAnimatedTransitioning类来显示视图。以下类将模拟对以模式呈现的导航控制器的推送:

代码语言:javascript
复制
import UIKit
import PhotosUI

class SlideInModalPresentationController: UIPresentationController {
            
    var offset: CGFloat = 0.0
    
    override func containerViewWillLayoutSubviews() {
        super.containerViewWillLayoutSubviews()
        presentedView?.frame.origin.y = offset
        presentedView?.frame.size.height -= offset
        presentedView?.layer.cornerRadius = 10
        presentedView?.clipsToBounds = true
    }
}

class SlideInTransition: NSObject, UIViewControllerAnimatedTransitioning {
    
    private let duration = 0.3
    var isPresenting: Bool = true
    var dismissModally: Bool = false
    
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return duration
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let toController = transitionContext.viewController(forKey: .to),
            let fromController = transitionContext.viewController(forKey: .from)
        else { return}
        if isPresenting {
            toController.view.frame.origin.x = fromController.view.frame.width
            transitionContext.containerView.addSubview(toController.view)
            UIView.animate(withDuration: duration, animations: {
                toController.view.frame.origin.x = 0
            }, completion: { _ in
                transitionContext.completeTransition(true)
            })
        } else if dismissModally {
            var stack: UIView? = nil
            if #available(iOS 14, *), toController is PHPickerViewController {
                stack = toController.view.superview
                toController.dismiss(animated: false)
            } else if toController is UIImagePickerController {
                stack = toController.view.superview
                toController.dismiss(animated: false)
            }
            UIView.animate(withDuration: duration, animations: {
                stack?.frame.origin.y = fromController.view.frame.height
                fromController.view.frame.origin.y = fromController.view.frame.height
            }, completion: { _ in
                transitionContext.completeTransition(true)
                fromController.view.removeFromSuperview()
            })
        } else {
            UIView.animate(withDuration: duration, animations: {
                fromController.view.frame.origin.x = fromController.view.frame.width
            }, completion: { _ in
                transitionContext.completeTransition(true)
                fromController.view.removeFromSuperview()
            })
        }
    }
}

若要在视图控制器中实现:

代码语言:javascript
复制
class ViewController: UIViewController {

    let slidInTransition = SlideInTransition()
}

extension ViewController: UIViewControllerTransitioningDelegate {
    
    private func presentYourController(_ image: UIImage) {
        let yourController = YourController()
        yourController.image = image
        yourController.modalPresentationStyle = .custom
        yourController.transitioningDelegate = self
        slidInTransition.dismissModally = false
        presentedViewController?.present(yourController, animated: true)
    }
    
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        let presentationController = SlideInModalPresentationController(presentedViewController: presented, presenting: presenting)
        presentationController.offset = view.convert(source.view.frame, to: nil).origin.y + 10
        return presentationController
    }
    
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        slidInTransition.isPresenting = true
        return slidInTransition
    }
    
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        slidInTransition.isPresenting = false
        return slidInTransition
    }

    private func dismissPhotoStack() {
        slidInTransition.dismissModally = true
        presentedViewController?.dismiss(animated: true)
    }
}

当您准备关闭整个堆栈时,可以调用dismissPhotoStack。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65722982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档