Swift在将图像传递给另一个ViewController时解开一个Optional值时意外发现nil

时间:2018-07-10 07:33:08

标签: swift image picker

我有两个VC。第一个包含来自图库的imagePicker和将图像发送到chatLog的回调函数...我想将选定的照片发送至第二个VC

if let selectedImage = selectedImageFromPicker {

        //self.callback?(selectedImage)
        detailImageViewController.aImage = selectedImage
}

我使用取消接受按钮创建了第二个VC作为PreviewImage的控制器。我试图通过这种方式将第二个VC上显示的图像传回第一个VC,但显示给我:

  

致命错误:在展开可选值时意外发现nil。

我该如何解决?

var t : EVTPhotoTekingHelper!

@objc func actionSend() {

    if aImage != nil{
        t.callback?(aImage!)
    }
    else {
        print("nil")
    }

    dismiss(animated: true, completion: nil)
}

已更新

我的第一个风投

typealias PhotoTekingHelperCallBack = (UIImage?) -> ()

class EVTPhotoTekingHelper: NSObject {

// View controller on which AlertViewController and UIImageViewController are present
weak var viewController: UIViewController!

var imagePickerController: UIImagePickerController?
var callback: PhotoTekingHelperCallBack?
var photoTakinHelper: EVTPhotoTekingHelper!

// MARK: - Initialization

init(viewController: UIViewController, callback: @escaping PhotoTekingHelperCallBack) {

    self.viewController = viewController
    self.callback = callback

    super.init()

    showPhotoSourceSelection()
}

func showPhotoSourceSelection() {

    let alertController = UIAlertController.init(title: nil,
                                                 message: "Message?",
                                                 preferredStyle: .actionSheet)

    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
    let photoLibraryAction = UIAlertAction(title: "from library", style: .default) { (action) in

        self.showImagePickerController(sourceType: .photoLibrary)

    }

    alertController.addAction(cancelAction)
    alertController.addAction(photoLibraryAction)


    if UIImagePickerController.isFlashAvailable(for: .rear) {

        let cameraAction = UIAlertAction.init(title: "from camera", style: .default, handler: { (action) in

            self.showImagePickerController(sourceType: .camera)
        })

        alertController.addAction(cameraAction)
    }

    viewController.present(alertController, animated: true, completion: nil)
}

func showImagePickerController(sourceType: UIImagePickerControllerSourceType) {

    imagePickerController = UIImagePickerController.init()
    imagePickerController!.sourceType = sourceType
    imagePickerController!.delegate = self

    viewController.present(imagePickerController!, animated: true, completion: nil)
}
}

第一个VC的扩展

extension EVTPhotoTekingHelper: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {


    var selectedImageFromPicker: UIImage?

    if let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
        selectedImageFromPicker = editedImage
    } else if let originImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
        selectedImageFromPicker = originImage
    }

    let detailImageViewController = EVImagePreviewController()
    let ncDetailImageViewController = UINavigationController(rootViewController: detailImageViewController)
    if let selectedImage = selectedImageFromPicker {

        //self.callback?(selectedImage)
        detailImageViewController.aImage = selectedImage
    }
    viewController.dismiss(animated: false, completion: nil)
    viewController.parent?.present(ncDetailImageViewController, animated: true, completion: nil)

}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    viewController.dismiss(animated: false, completion: nil)
}
}

我的第二个VC

class EVImagePreviewController: UIViewController, UIScrollViewDelegate {

var t : EVTPhotoTekingHelper!
var aImageView: UIImageView!
var aImage: UIImage!

private var aScrollView: UIScrollView!

override func viewDidAppear(_ animated: Bool) {


    aImageView = UIImageView(frame: CGRect(x: 0, y: 75, width: (aImage?.size.width)!, height: (aImage?.size.height)!))
    aImageView.contentMode = .scaleAspectFit
    aImageView.image = aImage

    aScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
    aScrollView.backgroundColor = .clear
    aScrollView.contentSize = CGSize(width: view.frame.size.width, height: view.frame.height)
    aScrollView.minimumZoomScale  = 0.2
    aScrollView.maximumZoomScale  = 2.3
    aScrollView.clipsToBounds     = true
    aScrollView.delegate = self

    aScrollView.addSubview(aImageView)

    view.addSubview(aScrollView)

    aImageView.center = CGPoint(x: aScrollView.bounds.midX, y: aScrollView.bounds.midY - 35)
}

override func viewDidLoad() {
    super.viewDidLoad()

    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", style: .plain, target: self, action: #selector(actionSend))
    navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(actionBack))

}

// MARK: - IBAction

@objc func actionBack() {

    dismiss(animated: false, completion: nil)
}

@objc func actionSend() {

    print("\(t)")
    if aImage != nil{
        t.callback?(aImage!)
    }
    else {
        print("nil")
    }


    //self.callback?(aImage)
    dismiss(animated: true, completion: nil)
}

// MARK: - UIScrollViewDelegate

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return aImageView
}

func scrollViewDidZoom(_ scrollView: UIScrollView) {

    let subView = scrollView.subviews[0]

    let offsetX = max((scrollView.bounds.width - scrollView.contentSize.width) * 0.5, 0.0)
    let offsetY = max((scrollView.bounds.height - scrollView.contentSize.height) * 0.5, 0.0)

    subView.center = CGPoint(x: scrollView.contentSize.width * 0.5 + offsetX, y: scrollView.contentSize.height * 0.5 + offsetY)
}
}

1 个答案:

答案 0 :(得分:0)

在这里,您需要先从第一个视图控制器的父级中展示第二个视图控制器,然后再将其关闭:

viewController.dismiss(animated: false, completion: nil)

到目前为止,对我来说没有任何意义。不清楚回调实现在哪里。

  

我猜nil异常肯定不是UIImage的。它的某个地方   在您的回调实现中。