如何使用 NSUserDefaults 将图像从 Collection View 传递到 Xcode 中的 Detail VC

How to pass an image from Collection View to Detail VC in Xcode using NSUserDefaults

我正在尝试将图像从我的 Collection 视图 (PortfolioView.swift) 传递到另一个视图控制器 (PortfolioDetail.swift)。我的 PortfolioView.swift 代码如下:

import UIKit

class Portfolio View: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
    var array = [String] = []
    var name : AnyObject? {
        get {
            return NSUserDefaults.standardUserDefaults().objectForKey("name")
    }
        set {
            NSUserDefaults.standardUserDefaults.setObject(newValue!, forKey: "name")
            NSUserDefaults.standardUserDefaults().synchronize()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        array = ["PortImage1","PortImage2","PortImage3","PortImage4","PortImage5","PortImage6","PortImage7",
    "PortImage1","PortImage2","PortImage3","PortImage4","PortImage5","PortImage6","PortImage7",
    "PortImage1","PortImage2","PortImage3","PortImage4","PortImage5","PortImage6","PortImage7"]
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: "BackgroundImage.png")!)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func collectionView(collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
        return array.count
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! CollectionViewCell
        cell.ImageView.image = UIImage(named: array[indexPath.row])
        cell.ImageView.layer.cornerRadius = cell.ImageView.frame.size.width / 2
        cell.ImageView.clipsToBounds = true
        cell.ImageView.layer.borderWidth = 2.0
        cell.ImageView.layer.borderColor = UIColor.whiteColor().CGColor
        return cell
    }
    func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
        name = UIImage(named: array[indexPath.row])
    }
}

我的 PortfolioDetail.swift 代码为:

import UIKit

class PortfolioDetail: UIViewController {
    @IBOutlet var DetailImageView: UIImage!
    @IBOutlet var DetailLabel: UILabel!

    var name: AnyObject? {
        get {
            return NSUserDefaults.standardUserDefaults().objectForKey("name")
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: "BackgroundImage.png")!)
        DetailImageView.image = UIImage(named: name as! String)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

当我 运行 这个应用程序时,我可以显示我的图像数组,但是当我点击其中一张图像时,它不会显示我的其他图像中的图像 VC .我认为我的问题与以下行有关:

DetailImageView.image = UIImage(named: name as! String)

您正在 NSUserDefaults 中保存一个 UIImage,然后试图将其用作 String - 这不会起作用,因为这两种类型不兼容。使事情正常进行的最简单方法是更改​​
name = UIImage(named: array[indexPath.row])

name = array[indexPath.row]

这样,您将把图片的名称保存在NSUserDefaults中,以后可以根据它加载图片。


现在,正如评论中所说的那样——以这种方式在视图控制器之间传递数据并不是一个好的设计选择。最好的方法是直接传递 name - 有两种方法可以做到这一点,具体取决于您如何移动到 PortfolioDetail 视图控制器 - 通过 segue 或 "directly" (即自己实例化它在代码中调用 presentViewController).

如果你用 segue 做这个,你应该添加(如果你没有)这个方法:

override func prepareForSegue(_ segue: UIStoryboardSegue, sender sender: AnyObject?) {

    if (segue.identifier == "YourSegueIdentifier") {
        let portfolioDetail = segue.destinationViewController as! PortofolioDetail
        portfolioDetail.name = self.name
    }

}

如果直接实例化它,它应该看起来像这样:

let portfolioDetailVC = PortfolioDetail()
portoflioDetailVC.name = self.name
self.presentViewController(portfolioDetailVC, animated: true, completion: nil)

您还需要删除两个视图控制器中 name 变量的自定义 getters 和 seterrs。