设置滚动视图的缩放比例并点击后退按钮崩溃程序



我试图制作一个程序,点击一个图像,它会分段显示在全屏上,缩放后周围没有空白(CS 193P任务4任务7,任何知道它的人都可以使用)。视图控制器嵌入导航控制器中。事实证明,当我点击导航栏中的后退按钮时,程序与EXC_BAD_ACCESS (code = EXC_I386_GPFLT)一起崩溃。

我发现我可以通过滚动到图像顶部然后返回来防止这种崩溃。另一种完全防止它的方法是注释掉设置scrollView的zoomScale的行。这是我用来加载和处理图像的代码:

import UIKit
class ImageViewController: UIViewController, UIScrollViewDelegate {
    @IBOutlet weak var scrollView: UIScrollView! {
        didSet {
            scrollView.contentSize = imageView.frame.size
            scrollView.delegate = self
            scrollView.minimumZoomScale = 0.03
            scrollView.maximumZoomScale = 5.0
        }
    }
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        return imageView
    }
    var imageURL: NSURL? {
        didSet {
            image = nil
            if view.window != nil {
                fetchImage()
            }
        }
    }
    private func fetchImage() {
        if let url = imageURL {
            let qos = Int(QOS_CLASS_USER_INITIATED.value)
            dispatch_async(dispatch_get_global_queue(qos, 0)) {
                let imageData = NSData(contentsOfURL: url)
                dispatch_async(dispatch_get_main_queue()) {
                    if url == self.imageURL {
                        if imageData != nil {
                            self.image = UIImage(data: imageData!)
                        } else {
                            self.image = nil
                        }
                    }
                }
            }
        }
    }
    private var imageView = UIImageView()
    private var image: UIImage? {
        get { return imageView.image }
        set {
            imageView.image = newValue
            imageView.sizeToFit()
            scrollView?.contentSize = imageView.frame.size
            scrollViewDidScrollOrZoom = false
            autoScale()
        }
    }
    private var scrollViewDidScrollOrZoom = false
    private func autoScale() {
        if scrollViewDidScrollOrZoom {
            return
        }
        if let sv = scrollView {
            if image != nil {
                sv.zoomScale = max(sv.bounds.size.width / image!.size.width, sv.bounds.size.height / image!.size.height)
                sv.contentOffset = CGPoint(x: (imageView.frame.size.width - sv.frame.size.width) / 2, y: (imageView.frame.size.height - sv.frame.size.height) / 2)
                scrollViewDidScrollOrZoom = false
            }
        }
    }

    func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView!, atScale scale: CGFloat) {
        scrollViewDidScrollOrZoom = true
    }
    func scrollViewDidScroll(scrollView: UIScrollView) {
        scrollViewDidScrollOrZoom = true
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.addSubview(imageView)
    }
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        if image == nil {
            fetchImage()
        }
    }
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        autoScale()
    }
}

我试图制作一个简单的应用程序,它从一个只有按钮并嵌入导航控制器的视图控制器分割到ImageViewController,但崩溃仍然是一样的。这是我在第一个视图控制器中使用的代码:

class FirstViewController: UIViewController {
    let url = NSURL(string: "https://developer.apple.com/swift/images/swift-og.png")
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "Show Full Image" {
            let ivc = segue.destinationViewController as! ImageViewController
            ivc.imageURL = url
        }
    }
}

是什么原因造成的?我是不是做错了什么?我使用的是Xcode 6.3 beta 3。

问题似乎实际上与scrollView的委托有关,因为我可以通过添加来解决这个问题

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    scrollView.delegate = nil
}

最新更新