我的TableViewCell自定义类中的IbOutlet永远不会被初始化

时间:2016-06-08 10:03:50

标签: ios swift uitableview swift2

我有这个问题。我无法从任何地方访问我的插座,因为如果我不把它包装成可选的应用程序崩溃说总是“发现意外的零......” 如果我打开它它不会崩溃但永远不会被初始化。 从nib方法唤醒我从未从自定义类shopsTableViewCell : UITableViewCell调用 我已经堆栈溢出并读取如果你假装从故事板加载自定义单元格你必须注释这一行,否则它将覆盖当前实例,所以我评论了这一行:

tableView.registerClass(shopsTableViewCell.self, forCellReuseIdentifier: "cell")

但是现在我得到了错误:

  

由于未捕获的异常而终止应用   NSInternalInconsistencyException,原因:无法使单元格出列   带标识符单元格 - 必须注册一个笔尖或一个类   标识符或连接故事板中的原型单元

在故事板中,我已经检查了文件的所有者,因为它链接到自定义类,所以它们也很好,而且出口也做得很好。

这是我的ViewController班级代码:

import Foundation
import UIKit
import CoreLocation
import MapKit


class showShopsTableView : ViewController, UITableViewDelegate, UITableViewDataSource,UISearchBarDelegate, UISearchResultsUpdating {
    var selectedRow : shopsTableViewCell!
var index : Int = 0
@IBOutlet var searchBar: UISearchBar!

@IBOutlet var tableView: UITableView!


let resultSearchController = UISearchController(searchResultsController:nil)

var searchActive : Bool = false
var filtered:[String] = []


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

    //Configure TableView
    addTableViewToView()

    //Clean array data
    TableData.removeAll()

    //Retrieve data asynchronously
    let call = webApi()
    call.retrieveAllShops(self.tableView)




}

private func addTableViewToView(){

    tableView = UITableView(frame: UIScreen.mainScreen().bounds, style: UITableViewStyle.Plain)
    tableView.delegate = self
    tableView.dataSource = self
    searchBar.delegate = self
    tableView.registerClass(shopsTableViewCell.self, forCellReuseIdentifier: "cell")

    resultSearchController.searchResultsUpdater = self
    resultSearchController.searchBar.sizeToFit()
    resultSearchController.searchBar.delegate = self

    resultSearchController.searchBar.scopeButtonTitles = ["Filter", "Map"]


    tableView.tableHeaderView = resultSearchController.searchBar


    self.view.addSubview(self.tableView)
}



override func viewDidLayoutSubviews() {
    if let rect = self.navigationController?.navigationBar.frame {
        let y = rect.size.height + rect.origin.y
        self.tableView.contentInset = UIEdgeInsetsMake( y, 0, 0, 0)
    }
}

//Segue Method
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let destinationViewController = segue.destinationViewController as! detailViewShop
    destinationViewController.dataSend = self.selectedRow

    destinationViewController.titleText = self.selectedRow.shopTitle // set your properties here
    destinationViewController.descriptionText = self.selectedRow.shopDesc

    destinationViewController.imageOutlet = self.selectedRow.shopImageTitle

    destinationViewController.shopCategory = self.selectedRow.shopCategory

    destinationViewController.brands = self.selectedRow.Brands

}


//TableView Delegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    selectedRow = tableView.cellForRowAtIndexPath(indexPath)! as! shopsTableViewCell

    self.performSegueWithIdentifier("cell", sender: self)
}


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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell : shopsTableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! shopsTableViewCell
    if(searchActive){
        cell.textLabel?.text = filtered[indexPath.row]
    } else {
        cell.textLabel?.text = TableData[indexPath.row]
    }


    cell.textLabel?.numberOfLines = 0
    cell.textLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
    let image : UIImage = UIImage(named: "versace_shop.jpg")!
    cell.imageView?.image = image

    cell.shopImg = UIImageView.init(image: UIImage.init(named:"versace_shop.jpg"))
    let arrayIndex : String = "\(self.index)"
    let data = nsDict.objectForKey(arrayIndex)
    print(data)
    //Title
    cell.shopTitle = data?.objectForKey("name") as? String
    cell.shopName?.text = "alfredo"
    //Description
    cell.shopDesc = data?.objectForKey("name") as? String
    //Description
    cell.shopCategory = data?.objectForKey("Type") as? String
    //Brands
    cell.Brands = data?.objectForKey("Brands") as? String



    self.index += 1
    return cell
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 100
}
//SearchBar Delegate Methods
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
    searchActive = true;
}

func searchBarTextDidEndEditing(searchBar: UISearchBar) {
    searchActive = false;
}

func searchBarCancelButtonClicked(searchBar: UISearchBar) {
    searchActive = false;
}

func searchBarSearchButtonClicked(searchBar: UISearchBar) {
    searchActive = false;
}

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

    filtered = TableData.filter({ (text) -> Bool in
        let tmp: NSString = text
        let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
        return range.location != NSNotFound
    })
    if(filtered.count == 0){
        searchActive = false;
    } else {
        searchActive = true;
    }
    self.tableView.reloadData()
}

func updateSearchResultsForSearchController(searchController: UISearchController) {

}

func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
    filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}
func filterContentForSearchText(searchText: String, scope: String = "All") {
    tableView.reloadData()
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

这是我的自定义tableViewCell类代码::

import Foundation

import UIKit

class shopsTableViewCell : UITableViewCell{

    @IBOutlet weak var shopName: UILabel!

    @IBOutlet weak var shopImg: UIImageView!

    @IBOutlet weak var shopDescription: UILabel!

    @IBOutlet weak var label2: UILabel!
    @IBOutlet weak var label1: UILabel!

    var shopTitle : String?
    var shopDesc : String?
    var shopImageTitle : String?
    var shopCategory : String?
    var Brands : String?


    override func awakeFromNib() {
        super.awakeFromNib()

    }


    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

    }
}

编辑展示原型: enter image description here enter image description here

enter image description here

编辑添加插座图片:

enter image description here

这是retrieveAllShopsMethod

的代码
    func retrieveAllShops(tableView : UITableView){
        setGetShopsListUrl()

        call(tableView)
    }

    private func setGetShopsListUrl(){
        userApiCallUrl += "shops/all"
    }

private func call(tableView : UITableView){
        let request = NSMutableURLRequest(URL: NSURL(string: userApiCallUrl)!)

        request.HTTPMethod = "POST"

        request.HTTPBody = postParam.dataUsingEncoding(NSUTF8StringEncoding)
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
            guard error == nil && data != nil else {
                // check for fundamental networking error
                print("error=\(error)")
                return
            }
            if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
                // check for http errors
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(response)")
            }


            let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)

            let json: AnyObject? = responseString!.parseJSONString

            self.parseJson((json as! NSMutableArray), tableView: tableView)

        }

        task.resume()
    }

    private func parseJson(json : NSMutableArray, tableView : UITableView){

        var c : Int = 0
        for j in json {

            //Create main value
            guard let value = j.valueForKey("value")?.valueForKey("value")! else{
                continue
            }

            //Get name
            guard let Name : String = (value.valueForKey("Name")?.valueForKey("en") as? String) else {
                continue
            }
         TableData.append(Name)
        }

        doTableRefresh(tableView);
    }

TableData是一个全局var:

var TableData:Array< String > = Array < String >()

2 个答案:

答案 0 :(得分:1)

选择原型单元格,转到

attributes inspector -> table view cell -> identifier并确保您将其称为cell

答案 1 :(得分:1)

看来你在storyboard中设置了tableView,但是还有代码在viewController中设置它,可能会导致问题。如果事实在故事板中正确连接,您可以删除:

addTableViewToView(),删除以下行,因为它们已经(或可以)在故事板中设置:

tableView = UITableView(frame: UIScreen.mainScreen().bounds, style: UITableViewStyle.Plain)
    tableView.delegate = self
    tableView.dataSource = self
    tableView.registerClass(shopsTableViewCell.self, forCellReuseIdentifier: "cell")

另外,你能从故事板上显示tableView上的插座吗?你也可能有不必要的出口。

<强> TIPS

关于代码的一些友好反馈:

  • 班级名称应以大写字母开头。
  • 常量/变量应以小写字母开头。
  • 您有一个标识为cell的segue和单元格。应该是独特的和描述性的。
  • UIKit包括基金会。无需同时导入(尽管它没有任何损害)。

这些提示/最佳做法将帮助其他人更轻松地检查您的代码。