[英]How to pass data via segue from one View Controller to another with optionals
I am trying to get my data to pass from one view to the next when I click on an NSCollectionViewItem.当我单击 NSCollectionViewItem 时,我试图让我的数据从一个视图传递到另一个视图。 When an item is clicked I simply want to pass some data to a new view for a more "detailed" view of each item.当一个项目被点击时,我只想将一些数据传递给一个新视图,以获得每个项目的更“详细”视图。
I keep getting "fatal error: unexpectedly found nil while unwrapping an Optional value".我不断收到“致命错误:在展开可选值时意外发现 nil”。 I feel like I am missing a key step in the ProductDetail.swift file.我觉得我在 ProductDetail.swift 文件中遗漏了一个关键步骤。 The error occurs at the bottom of ViewController.swift in my prepare() method.错误发生在我的 prepare() 方法中 ViewController.swift 的底部。 The process on how to do this for OS X is completely different than iOS so any help would be greatly appreciated.如何为 OS X 执行此操作的过程与 iOS 完全不同,因此将不胜感激任何帮助。
ViewController.swift视图控制器.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 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 ProductDetail.swift
import Cocoa
class ProductDetail: NSViewController {
@IBOutlet weak var testLabel: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
}
}
I ended up figuring it out.我终于弄清楚了。 It was much simpler than I thought.这比我想象的要简单得多。 I needed to create a variable to hold the new data being passed in. Thank you to Santosh for his help and guidance.我需要创建一个变量来保存传入的新数据。感谢 Santosh 的帮助和指导。
ProductDetail.swift ProductDetail.swift
class ProductDetail: NSViewController {
@IBOutlet weak var testLabel: NSTextField!
var theBigPass = String()
override func viewDidLoad() {
super.viewDidLoad()
testLabel.stringValue = theBigPass
}
}
ViewController.swift Segue Methods ViewController.swift 转场方法
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
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.