【问题标题】:How to pass data via segue from one View Controller to another with optionals如何通过 segue 将数据从一个视图控制器传递到另一个具有选项的视图控制器
【发布时间】:2016-10-11 20:13:47
【问题描述】:

当我单击 NSCollectionViewItem 时,我试图让我的数据从一个视图传递到下一个视图。单击一个项目时,我只想将一些数据传递给一个新视图,以获得每个项目的更“详细”视图。

我不断收到“致命错误:在展开可选值时意外发现 nil”。我觉得我错过了 ProductDetail.swift 文件中的一个关键步骤。错误发生在我的 prepare() 方法中 ViewController.swift 的底部。如何为 OS X 执行此操作的过程与 iOS 完全不同,因此我们将不胜感激。

ViewController.swift

import Cocoa

class ViewController: NSViewController {


@IBOutlet weak var colView: NSCollectionView!

var productCategories: [ProductCategory]?

var productsArray: [ProductModel]?

var detailLabel: test1? 



override func viewWillAppear() {
    super.viewWillAppear()

    preferredContentSize = NSSize(width: 1025, height: 1200)

}

override func viewDidLoad() {

    super.viewDidLoad()

    getJSON()

}

func getJSON() {

    let requestURL: NSURL = NSURL(string: "http://myurl.php")!
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL as URL)
    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest as URLRequest) {
        (data, response, error) -> Void in

        let httpResponse = response as! HTTPURLResponse
        let statusCode = httpResponse.statusCode



        if (statusCode == 200) {

            do{

                let json = try JSONSerialization.jsonObject(with: data!, options:.mutableContainers)

                self.productsArray = [ProductModel]()

                if let products = json as? [[String: Any]] {

                    for product in products {

                        let testproduct = ProductModel()

                        testproduct.product_name = product["product_name"] as? String
                        testproduct.product_price = product["product_price"] as? String
                        testproduct.product_image = product["product_image"] as? String



                        self.productsArray?.append(testproduct)



                    }

                    DispatchQueue.main.async(){

                        self.colView.reloadData()
                    }
                }

            }catch {

                print("Error parsing the JSON: \(error)")
            }

        }
    }

    task.resume()

}

override var representedObject: Any? {
    didSet {
    // Update the view, if already loaded.
    }
}

}

extension ViewController: NSCollectionViewDataSource, NSCollectionViewDelegate{


func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {

    return productsArray?.count ?? 0
}


func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {

    let item = collectionView.makeItem(withIdentifier: "test1", for: indexPath) as! test1

        item.buildProduct  = productsArray?[indexPath.item]

    return item
}

func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {

    print("selected")

    self.performSegue(withIdentifier: "showProductDetail", sender: self)



}
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {


    if (segue.identifier == "showProductDetail") {

        if let detailVC = segue.destinationController as? ProductDetail {

        detailVC.testLabel.stringValue = (detailLabel?.label.stringValue)!

        }else{
            detailLabel?.label.stringValue = "failed"
        }


    }


}
}

test1.swift

import Cocoa

class test1: NSCollectionViewItem {

@IBOutlet weak var label: NSTextField!
@IBOutlet weak var label2: NSTextField!
@IBOutlet weak var productImageView: NSImageView!

var productItem: ProductModel?


var buildProduct: ProductModel? {

    didSet{

        label.stringValue = (buildProduct?.product_name)!
        label2.stringValue = (buildProduct?.product_price)!


        setupAppIconImage()
    }
}


override func viewDidLoad() {

    super.viewDidLoad()

}


func setupAppIconImage() {

    if let appIconImageURL = buildProduct?.product_image {
        let url = NSURL(string: appIconImageURL)

        URLSession.shared.dataTask(with: url! as URL,completionHandler:{(data, response, error) in

            if error != nil {
                print(error)
                return
            }

            self.productImageView.image = NSImage(data: data!)

        }).resume()

    }

}
}

ProductDetail.swift

import Cocoa

class ProductDetail: NSViewController {



@IBOutlet weak var testLabel: NSTextField!


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

}

【问题讨论】:

  • 尝试用let item = collectionView.item(at: indexPaths) as! test1 detailLabel = item在你的didSelectItemAt方法中初始化它
  • 试试这个:let selectedIndexPath = collectionView.selectionIndexPaths.first let item = collectionView.item(at: selectedIndexPath!) detailLabel = item
  • 是的,因为它没有你需要在访问它之前为其设置值的值。
  • 您正在做正确的事情,将数据从一个 VC 传递到另一个 VC,但是当您拥有数据时,只有您可以传递对吗?因此,当您选择一个项目时,您需要捕获该值以便您可以传递,您可以在前面提到的 didselect 中完成此操作
  • 你能够捕获要传递的值真是太好了。现在检查您的 testLabel 是否在 ProductDetail xib/storyboard 中正确连接。还要确保你在故事板中定义了 segue。

标签: swift macos segue swift3 nsstoryboard


【解决方案1】:

我最终弄明白了。这比我想象的要简单得多。我需要创建一个变量来保存传入的新数据。感谢 Santosh 的帮助和指导。

ProductDetail.swift

class ProductDetail: NSViewController {

@IBOutlet weak var testLabel: NSTextField!

var theBigPass = String()


override func viewDidLoad() {
    super.viewDidLoad()


    testLabel.stringValue = theBigPass

}

}

ViewController.swift Segue 方法

func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {

    print("selected")

    let selectedIndexPath = collectionView.selectionIndexPaths.first
    let item = collectionView.item(at: selectedIndexPath!)
    detailLabel = item as! test1?

    self.performSegue(withIdentifier: "showProductDetail", sender: self)


}

override func prepare(for segue: NSStoryboardSegue, sender: Any?) {



    if (segue.identifier == "showProductDetail") {


        if let detailVC = segue.destinationController as? ProductDetail {

            let passed = (detailLabel?.label.stringValue)!

            detailVC.theBigPass = passed


        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-13
    相关资源
    最近更新 更多