Segue和使用instantiateViewController有什么区别?

时间:2018-01-12 04:24:23

标签: ios swift

segue和instantiateViewController有什么区别?

我一直在试图弄清楚如何使用segue将图像从一个视图控制器发送到另一个视图控制器,2个答案(Passing Image to another View Controller (Swift)How do I segue an image to another ViewController and display it within an ImageView?)都说使用segues但是在尝试时使用segues我遇到了一些问题,比如第二个视图控制器在照片库被解除后没有显示或图像没有显示。

Segue示例

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.destination is XferImageViewController {
        print("Test: ", pickedImage.image)
        let xferVC = segue.destination as? XferImageViewController
        xferVC?.storedImage = pickedImage.image
    }
    print("WHAT IS GOING ON")
//        if segue.destination is XferImageViewController {
//            let xferVC = segue.destination as? XferImageViewController
//            print(pickedImage.image)
//            //xferVC?.storedImage = pickedImage.image
//            xferVC?.storedImage = pickedImageVar
//        }

}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        pickedImage.image = image
    } else {
        print("Something went wrong")
    }
    let image = info[UIImagePickerControllerOriginalImage] as? UIImage
    dismiss(animated:true, completion: nil)
    performSegue(withIdentifier: "xferImage", sender: self)
}

InstantiateViewController示例

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        pickedImage.image = image
    } else {
        print("Something went wrong")
    }
    let image = info[UIImagePickerControllerOriginalImage] as? UIImage
    dismiss(animated:true, completion: nil)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = storyboard.instantiateViewController(withIdentifier: "xferImage") as! XferImageViewController
    controller.storedImage = image
    present(controller, animated: true, completion: nil)
}

因此在使用InstantiateViewController而不是segue后,我得到了我想要的结果。两者有什么区别? (我确保那个segue标识符,试过segue.destination和storyboard ID,但仍然没有得到我需要的东西)有可能我不知道如何在照片库解雇电话后使用segue但仍想知道差异。

2 个答案:

答案 0 :(得分:3)

问题在于,当您启动segue时,segue特别关注视图控制器层次结构的状态。您必须推迟performSegue(withIdentifier:sender:),直到dismiss完成,即将其放入dismiss的完成句柄中:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        pickedImage.image = image
    } else {
        print("Something went wrong")
    }

    dismiss(animated: true) {
        self.performSegue(withIdentifier: "xferImage", sender: self)
    }
}

以上对我来说很好。

顺便说一句,您可以简化prepare(for:sender:)实施:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let xferVC = segue.destination as? XferImageViewController {
        xferVC.storedImage = pickedImage.image
    }
}

两个有些不相关的观察结果:

  1. 如果pickedImage是图片视图,我建议将其重命名(并将故事板中的插座更新)到pickedImageView。避免UIImage属性与UIImageView出口混淆是一个很好的惯例。

  2. 这是一个更小的观察,但在Model-View-Controller设计中,你通常不想依赖UIKit对象,如UIImageView来保存模型对象,即选中的图像。它表明" view"之间存在概念上的混淆。对象和"模型"对象。另外,如果当前视图控制器没有UIImageView

    ,该怎么办?

    我个人建议将所选图像存储在单独的UIImage?属性中:

    private var selectedImage: UIImage?
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
            selectedImage = image
    
            // if you also want to update a `UIImageView` in the current
            // view controller, fine, do that, but it shouldn't be confused
            // with the "model".
            //
            // pickedImageView.image = image
        } else {
            print("Something went wrong")
        }
    
        dismiss(animated: true) {
            self.performSegue(withIdentifier: "xferImage", sender: self)
        }
    }
    

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let xferVC = segue.destination as? XferImageViewController {
            xferVC.storedImage = selectedImage
        }
    }
    

答案 1 :(得分:0)

尝试使用下面的函数

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
    if segue.identifier == "segue"
    {
        if let xferVC = segue.destination as? XferImageViewController {
            xferVC.storedImage = pickedImage.image

                //Why Optional here ?
                //xferVC?.storedImage = pickedImage.image
            }
        }  
  }