2016-10-11 3 views
1

Ich versuche, meine Daten von einer Ansicht zur nächsten zu übertragen, wenn ich auf ein NSCollectionViewItem klicke. Wenn ein Objekt angeklickt wird, möchte ich einfach einige Daten an eine neue Ansicht übergeben, um eine detailliertere Ansicht jedes Objekts zu erhalten.Wie man Daten über den Übergang von einem View Controller zu einem anderen mit Optionals weiterleitet

Ich bekomme immer "fataler Fehler: unerwartet gefunden Null beim Auspacken ein optionaler Wert". Ich habe das Gefühl, dass mir ein Schlüsselschritt in der ProductDetail.swift-Datei fehlt. Der Fehler tritt am Ende von ViewController.swift in meiner prepare() -Methode auf. Der Vorgang, wie dies für OS X durchgeführt wird, ist völlig anders als bei iOS, daher würde jede Hilfe sehr geschätzt werden.

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() 
} 

} 
+0

Wo initialisieren Sie Ihre 'detailLabel' Variable in' ViewController'? Es ist nicht initialisiert und daher ist es null. Ihre App stürzt ab. – Santosh

+1

Versuchen Sie, es in Ihrer Methode 'didSelectItemAt' mit' let item = collectionView.item (at: indexPaths) as zu initialisieren! test1 detailLabel = item' – Santosh

+0

Ich habe Ihren Vorschlag versucht, aber ich habe eine Fehlermeldung "Kann nicht 'Element' mit einer Argumentliste des Typs '(unter: Set )" –

Antwort

1

I endete damit, es herauszufinden. Es war viel einfacher als ich dachte. Ich musste eine Variable erstellen, um die neuen Daten zu speichern. Danke an Santosh für seine Hilfe und Führung.

ProductDetail.swift

class ProductDetail: NSViewController { 

@IBOutlet weak var testLabel: NSTextField! 

var theBigPass = String() 


override func viewDidLoad() { 
    super.viewDidLoad() 


    testLabel.stringValue = theBigPass 

} 

} 

ViewController.swift Segue Methoden

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 


     } 

    } 
} 
Verwandte Themen