通过segue将数组发送到新的视图控制器swift iOS 9

时间:2016-01-08 20:23:58

标签: ios swift tableview segue

我正在尝试将数据数组发送到新的视图控制器,我目前收到错误fatal error: unexpectedly found nil while unwrapping an Optional value

我正在使用www.thecocktaildb.com

中的API数据

实施例: http://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita

不确定我做错了什么。尝试在我的搜索视图控制器中的segue之前调试和检查值,它们是准确的。

继承我的代码:

主要故事板

enter image description here

SearchViewController

class SearchViewController: UIViewController, UISearchBarDelegate, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var TableView: UITableView!
    @IBOutlet weak var SearchBar: UISearchBar!

    var valueToPass:Drinks!
    var isSearching : Bool = false

    class Drinks {
        var idDrink: Int = 0
        var strDrink: String = ""
        var strCategory: String = ""

        var strAlcoholic: String = ""
        var strGlass: String = ""
        var strInstructions: String = ""

        var strDrinkThumb: String = ""

        var strIngredient1: String = ""
        var strIngredient2: String = ""
        var strIngredient3: String = ""
        var strIngredient4: String = ""
        var strIngredient5: String = ""
        var strIngredient6: String = ""
        var strIngredient7: String = ""
        var strIngredient8: String = ""
        var strIngredient9: String = ""
        var strIngredient10: String = ""
        var strIngredient11: String = ""
        var strIngredient12: String = ""
        var strIngredient13: String = ""
        var strIngredient14: String = ""
        var strIngredient15: String = ""

        var strMeasure1: String = ""
        var strMeasure2: String = ""
        var strMeasure3: String = ""
        var strMeasure4: String = ""
        var strMeasure5: String = ""
        var strMeasure6: String = ""
        var strMeasure7: String = ""
        var strMeasure8: String = ""
        var strMeasure9: String = ""
        var strMeasure10: String = ""
        var strMeasure11: String = ""
        var strMeasure12: String = ""
        var strMeasure13: String = ""
        var strMeasure14: String = ""
        var strMeasure15: String = ""
    }
    var TableData:Array< Drinks > = Array < Drinks >()

    override func viewDidLoad() {
        super.viewDidLoad()

        for subView in self.SearchBar.subviews
        {
            for subsubView in subView.subviews
            {
                if let textField = subsubView as? UITextField
                {
                    textField.attributedPlaceholder  = NSAttributedString(string: NSLocalizedString("Search", comment: ""))

                }
            }
        }

        self.SearchBar.delegate = self
        self.TableView.delegate = self
        self.TableView.dataSource = self
    }

    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {

        if self.SearchBar.text!.isEmpty {

            self.isSearching = false

        }else{

            self.isSearching = true

            let userSearchInput = self.SearchBar.text!.lowercaseString
            let newString = userSearchInput.stringByReplacingOccurrencesOfString(" ", withString: "%20", options: NSStringCompareOptions.LiteralSearch, range: nil)

            let postEndpoint: String = "http://www.thecocktaildb.com/api/json/v1/1/search.php?s=" + newString

            guard let url = NSURL(string: postEndpoint) else {
                print("Error: cannot create URL")
                return
            }

            let urlRequest = NSURLRequest(URL: url)
            let config = NSURLSessionConfiguration.defaultSessionConfiguration()
            let session = NSURLSession(configuration: config)

            let task = session.dataTaskWithRequest(urlRequest, completionHandler: { (data, response, error) in
                guard let responseData = data else {
                    print("Error: did not receive data")
                    return
                }
                guard error == nil else {
                    print("error calling GET on www.thecocktaildb.com")
                    print(error)
                    return
                }

                let post: NSDictionary
                do {
                    post = try NSJSONSerialization.JSONObjectWithData(responseData,
                        options: []) as! NSDictionary
                } catch  {
                    print("error trying to convert data to JSON")
                    return
                }

                var count = 1
                if let drinks = post["drinks"] as? [NSDictionary] {
                    self.TableData.removeAll()
                    for drink in drinks {
                        let adrink = Drinks()
                        if let strDrink = drink["strDrink"] as? String {
                            print(String(count) + ". " + strDrink)
                            adrink.strDrink = strDrink
                            count++
                        }
                        if let strCategory = drink["strCategory"] as? String {
                            print("    Category: " + strCategory)
                            adrink.strCategory = strCategory
                        }
                        if let strDrinkThumb = drink["strDrinkThumb"] as? String {
                            print("    Thumbnail Image: " + strDrinkThumb)
                            adrink.strDrinkThumb = strDrinkThumb
                        }
                        self.TableData.append(adrink)
                        self.TableView.reloadData()
                    }
                }
            })
            task.resume()

        }
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return TableData.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) 
        //title = TableData[indexPath.row].strDrink

        cell.textLabel?.text = TableData[indexPath.row].strDrink;

        let imageString = TableData[indexPath.row].strDrinkThumb

        if (imageString == ""){
            let noDrinkImage : UIImage = UIImage(named: "noimage.jpg")!
            cell.imageView!.image = noDrinkImage
        }else{
            let drinkImage =  UIImage(data: NSData(contentsOfURL: NSURL(string:TableData[indexPath.row].strDrinkThumb)!)!)
            cell.imageView!.image = drinkImage
        }
        return cell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        print(TableData[indexPath.row].strDrink)
        valueToPass = TableData[indexPath.row]
        //self.performSegueWithIdentifier("drinkSegue", sender: TableData[indexPath.row])
    }

    // hide kwyboard when search button clicked
    func searchBarSearchButtonClicked(searchBar: UISearchBar) {
        self.SearchBar.resignFirstResponder()
    }

    // hide keyboard when cancel button clicked
    func searchBarCancelButtonClicked(searchBar: UISearchBar) {
        self.SearchBar.text = ""
        self.SearchBar.resignFirstResponder()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

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

        if (segue.identifier == "DrinkSegue") {
            // initialize new view controller and cast it as your view controller
            let drinkViewController = segue.destinationViewController as! DrinkViewController
            // your new view controller should have property that will store passed value
            drinkViewController.passedValue = valueToPass
        }
    }
}

DrinkViewController.swift

class DrinkViewController: UIViewController {

    @IBOutlet weak var DrinkNameLabel: UILabel!
    var passedValue : SearchViewController.Drinks!

    override func viewDidLoad() {
        super.viewDidLoad()
        DrinkNameLabel.text = passedValue!.strDrink
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

1 个答案:

答案 0 :(得分:1)

这样做

didSelectRowAtIndexPath传递数组

self.performSegueWithIdentifier("drinkSegue", sender: TableData[indexPath.row])

您需要将数组传递给DrinkViewController

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
     if (segue.identifier == "DrinkSegue") {
            // initialize new view controller and cast it as your view controller
            let drinkViewController = segue.destinationViewController as! DrinkViewController
            // your new view controller should have property that will store passed value
            drinkViewController.passedValue = valueToPass
            // declare myArray in your drinkViewController and then assign it here
            // now your array that you passed will be available through myArray
            drinkViewController.myArray = sender
        }
    }

<强>更新
在我得到你的项目之后,我注意到你遇到的问题是你确实将一个segue从tableView直接拖到了drinkController - 发生了什么didSelectRowAtIndexPath将不会被调用而你的sender将永远是无drinkViewController.myArray = sender as! Drinks

我通过将segue从viewController拖到drinkController来改变它。