使用委托:在展开可选值时意外发现 nil
Using delegates: unexpectedly found nil while unwrapping an Optional value
我有两个 ViewController
,假设一个名为 MainVC
,另一个名为 GetCameraRollImageViewController
。在第二个中,有一个 UIScrollView
包含一个 UIImageView
,因为我使用 segue 来显示第二个视图控制器,所以我必须在 MainVC
中使用它的委托:
class ViewController: UIViewController, GetTextDelegate, GetCameraRollImageDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//
//other codes
//
@IBAction func setNewImageFromCameraRoll(segue:UIStoryboardSegue) {
if let newImageVC = segue.sourceViewController as? GetCameraRollImageViewController{
var scale:CGFloat = 1.0/newImageVC.scrollView.zoomScale;
var visibleRect:CGRect!
visibleRect.origin.x = newImageVC.scrollView.contentOffset.x * scale;
visibleRect.origin.y = newImageVC.scrollView.contentOffset.y * scale;
visibleRect.size.width = newImageVC.scrollView.bounds.size.width * scale;
visibleRect.size.height = newImageVC.scrollView.bounds.size.height * scale;
var cr:CGImageRef = CGImageCreateWithImageInRect(newImageVC.inputImage.image?.CGImage,visibleRect)
var cropped:UIImage = UIImage(CGImage: cr)!
imageView.image = cropped
}
}
}
GetCameraRollImageViewController
代码:
import UIKit
protocol GetCameraRollImageDelegate{
//
}
class GetCameraRollImageViewController: UIViewController, UIScrollViewDelegate {
var delegate:GetCameraRollImageDelegate? = nil
var inputImageDelegate:UIImage!
@IBOutlet var scrollView: UIScrollView!
@IBOutlet var inputImage:UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.minimumZoomScale = 0.5
self.scrollView.maximumZoomScale = 6.0
self.scrollView.contentSize = self.inputImage.frame.size;
self.scrollView.delegate = self
inputImage.image = inputImageDelegate
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return self.inputImage
}
}
但是当我触发 setNewImageFromCameraRoll()
时,应用程序崩溃并出现以下错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
注意: scrollView
和 inputImage
都是有界的,我不是在 viewDidLoad()
中阅读它们,而它们是空。
我不是 100%,但我相信您的问题是尚未创建 scrollView。尝试将图像传递给新的视图控制器并在 GetCameraRollImageViewController 的 viewDidLoad 中调整大小。
[根据评论更新]
行
var visibleRect:CGRect!
将 visibleRect
分配给 nil
,因此
的后续行
visibleRect.origin.x = newImageVC.scrollView.contentOffset.x * scale;
然后将取消引用 visibleRect
,找到 nil
并产生异常。你需要分配一个CGRect
,赋值给visibleRect
.
[原答案]
visibleRect
绑定了吗?看起来不是。如果这是绑定的,那么您会注意到 !
的其他用途...您需要绑定您的插座(通常在 InterfaceBuilder 中):
@IBOutlet var scrollView: UIScrollView!
@IBOutlet var inputImage:UIImageView!
也许 scrollView
未绑定,因此,因为它是隐式展开的(!
运算符),当您将其引用为 nil
时,您的程序将致命。
使用:
var visibleRect =
CGRectMake (newImageVC.scrollView.contentOffset.x * scale,
newImageVC.scrollView.contentOffset.y * scale,
newImageVC.scrollView.bounds.size.width * scale,
newImageVC.scrollView.bounds.size.height * scale)
您的代码有很多问题。
首先,为什么要有一个以segue为参数的IBAction?
通常你做的是通过任何方法调用一个segue,然后实现preformSegue方法。每当在视图控制器中触发 segue 时,都会调用该方法。
在 performSegue 中,您可以获得指向目标视图控制器的指针并将参数传递给它。
我不清楚您的 setNewImageFromCameraRoll 方法是如何被调用的,或者它是如何获得 segue 对象的。对我来说,您正在使用 segue 中的 source 视图控制器也没有意义。我怀疑该方法没有像您预期的那样工作。
下一个问题与您尝试对从 segue 获得的视图控制器执行的操作有关。您正在尝试直接操纵它的视图。不要那样做。您应该将视图控制器的视图视为私有的。相反,您应该向视图控制器添加属性以公开您需要的信息,并引用这些属性。
乱用另一个视图控制器的视图违反了封装原则。它还经常失败,因为其他视图控制器的视图在显示在屏幕上之前不会被创建。
根据我的说法,您还没有将 V2 class 的委托连接到 MainVC 中的自身
"newImageVC?.delegate=self"
我有两个 ViewController
,假设一个名为 MainVC
,另一个名为 GetCameraRollImageViewController
。在第二个中,有一个 UIScrollView
包含一个 UIImageView
,因为我使用 segue 来显示第二个视图控制器,所以我必须在 MainVC
中使用它的委托:
class ViewController: UIViewController, GetTextDelegate, GetCameraRollImageDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//
//other codes
//
@IBAction func setNewImageFromCameraRoll(segue:UIStoryboardSegue) {
if let newImageVC = segue.sourceViewController as? GetCameraRollImageViewController{
var scale:CGFloat = 1.0/newImageVC.scrollView.zoomScale;
var visibleRect:CGRect!
visibleRect.origin.x = newImageVC.scrollView.contentOffset.x * scale;
visibleRect.origin.y = newImageVC.scrollView.contentOffset.y * scale;
visibleRect.size.width = newImageVC.scrollView.bounds.size.width * scale;
visibleRect.size.height = newImageVC.scrollView.bounds.size.height * scale;
var cr:CGImageRef = CGImageCreateWithImageInRect(newImageVC.inputImage.image?.CGImage,visibleRect)
var cropped:UIImage = UIImage(CGImage: cr)!
imageView.image = cropped
}
}
}
GetCameraRollImageViewController
代码:
import UIKit
protocol GetCameraRollImageDelegate{
//
}
class GetCameraRollImageViewController: UIViewController, UIScrollViewDelegate {
var delegate:GetCameraRollImageDelegate? = nil
var inputImageDelegate:UIImage!
@IBOutlet var scrollView: UIScrollView!
@IBOutlet var inputImage:UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.minimumZoomScale = 0.5
self.scrollView.maximumZoomScale = 6.0
self.scrollView.contentSize = self.inputImage.frame.size;
self.scrollView.delegate = self
inputImage.image = inputImageDelegate
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return self.inputImage
}
}
但是当我触发 setNewImageFromCameraRoll()
时,应用程序崩溃并出现以下错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
注意: scrollView
和 inputImage
都是有界的,我不是在 viewDidLoad()
中阅读它们,而它们是空。
我不是 100%,但我相信您的问题是尚未创建 scrollView。尝试将图像传递给新的视图控制器并在 GetCameraRollImageViewController 的 viewDidLoad 中调整大小。
[根据评论更新]
行
var visibleRect:CGRect!
将 visibleRect
分配给 nil
,因此
visibleRect.origin.x = newImageVC.scrollView.contentOffset.x * scale;
然后将取消引用 visibleRect
,找到 nil
并产生异常。你需要分配一个CGRect
,赋值给visibleRect
.
[原答案]
visibleRect
绑定了吗?看起来不是。如果这是绑定的,那么您会注意到 !
的其他用途...您需要绑定您的插座(通常在 InterfaceBuilder 中):
@IBOutlet var scrollView: UIScrollView!
@IBOutlet var inputImage:UIImageView!
也许 scrollView
未绑定,因此,因为它是隐式展开的(!
运算符),当您将其引用为 nil
时,您的程序将致命。
使用:
var visibleRect =
CGRectMake (newImageVC.scrollView.contentOffset.x * scale,
newImageVC.scrollView.contentOffset.y * scale,
newImageVC.scrollView.bounds.size.width * scale,
newImageVC.scrollView.bounds.size.height * scale)
您的代码有很多问题。
首先,为什么要有一个以segue为参数的IBAction?
通常你做的是通过任何方法调用一个segue,然后实现preformSegue方法。每当在视图控制器中触发 segue 时,都会调用该方法。
在 performSegue 中,您可以获得指向目标视图控制器的指针并将参数传递给它。
我不清楚您的 setNewImageFromCameraRoll 方法是如何被调用的,或者它是如何获得 segue 对象的。对我来说,您正在使用 segue 中的 source 视图控制器也没有意义。我怀疑该方法没有像您预期的那样工作。
下一个问题与您尝试对从 segue 获得的视图控制器执行的操作有关。您正在尝试直接操纵它的视图。不要那样做。您应该将视图控制器的视图视为私有的。相反,您应该向视图控制器添加属性以公开您需要的信息,并引用这些属性。
乱用另一个视图控制器的视图违反了封装原则。它还经常失败,因为其他视图控制器的视图在显示在屏幕上之前不会被创建。
根据我的说法,您还没有将 V2 class 的委托连接到 MainVC 中的自身 "newImageVC?.delegate=self"