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但仍想知道差异。
答案 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
}
}
两个有些不相关的观察结果:
如果pickedImage
是图片视图,我建议将其重命名(并将故事板中的插座更新)到pickedImageView
。避免UIImage
属性与UIImageView
出口混淆是一个很好的惯例。
这是一个更小的观察,但在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
}
}
}