使用委托:在展开可选值时意外发现 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

注意: scrollViewinputImage 都是有界的,我不是在 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"