2015-05-30 47 views
1

=> Demo Project @ GitHub <=dequeueReusableCellWithIdentifier索引超出結合

我有一個UITableViewController具有TableView在我所具有另一TableView在它的細胞。

當該內部TableView試圖dequeueReusableCellWithIdentifier爲indexPath (1,0)應用程序崩潰與

Terminating app due to uncaught exception 'NSRangeException', 
reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]' 

雖然該內部TableView顯然有3個部分。堆棧跟蹤之中:

-[__NSArrayI objectAtIndex:] + 190 
-[UITableViewDataSource tableView:indentationLevelForRowAtIndexPath:] + 61 
-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1711 
+[UIView(Animation) performWithoutAnimation:] + 65 
-[UITableView _configureCellForDisplay:forIndexPath:] + 312 
-[UITableView dequeueReusableCellWithIdentifier:forIndexPath:] + 271 

因爲微量的,我試圖實現

override func tableView(tableView: UITableView, 
       indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int { 
    return 0 
} 

但隨後的應用程序崩潰的

-[UITableViewDataSource tableView:viewForFooterInSection:] 

與同index 1 beyond bounds [0 .. 0] ...

實現是相對無關恕我直言,但它是

override func tableView(tableView: UITableView, 
       cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    if tableView.tag == 0 { 
    return super.tableView(tableView, cellForRowAtIndexPath: indexPath) 
    } 
    if let cell = tableView.dequeueReusableCellWithIdentifier("cell") as? UITableViewCell { 
    return cell 
    } 
    return UITableViewCell() // Shouldn't happen. 
} 

我不會爲那最後一行感到驕傲:)但你還會做什麼來取悅編譯器?我從來沒有達到過這條線。崩潰很明顯發生在內部TableView其中tag爲1.

+0

你可以發佈完整的方法嗎? – Amit89

+0

你的'tableView:cellForRowAtIndexPath:'方法的實現是什麼? –

+0

@Amit89 @madboy我添加了我的'cellForRowAtIndexPath'實現,儘管在這種情況下我覺得這並不重要。就像我說的那樣,它在'出列'上崩潰。 –

回答

1

的問題是調用

super.tableView(tableView, cellForRowAtIndexPath: indexPath) 

MasterViewControllerUITableViewController一個子類,所以你調用基類UITableViewControllercellForRowAtIndexPath。我想理解你的代碼的意圖(「嗨,我想讓子cellForRowAtIndexPath在適當的情況下調用父代)」,但是你正在將類層次結構與視圖層次結構混爲一談。這不是實現你想要的方式。

相反,你可以這樣做:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    if tableView.tag == 0 { 
     return tableView.dequeueReusableCellWithIdentifier("ParentCell", forIndexPath: indexPath) as! UITableViewCell 
    } 

    return tableView.dequeueReusableCellWithIdentifier("ChildCell", forIndexPath: indexPath) as! UITableViewCell 
} 

此實例爲0tag,另一個用於1一種細胞類型。請注意,我更改了故事板以使兩個表視圖都可以使用動態原型,並且我已經如上所述更改了兩個表視圖的標識符。

坦率地說,我認爲讓一個對象嘗試作爲兩種不同類型的表視圖的委託是錯誤的。如果你真的有一個視圖控制器和兩個表視圖,我認爲爲每個表視圖實現一個自定義的委託對象要乾淨得多,根據需要實例化它們,設置合適的表視圖的delegatedataSource。這樣,您可以避免必須使用「如果表0執行x否則執行y」邏輯清空所有代表方法。

但是,更廣泛地說,我會建議針對tableview中的表視圖。

+0

你是完全正確的,這是一個錯誤。感謝您的真棒回答。 –

-1

你的第二條if語句應該被包裝在第一條(如果tableView.tag == 0)。現在,它被稱爲兩個tableViews,因此錯誤。

+0

不,如果'tag'爲零,他會調用'return'。 – Rob

0

我想我知道答案。基本上,我知道在另一個TableView中放置一個TableView並不是一個超級聰明的想法,第一個是Static,另一個是Dynamic(我應該說過)。

然後,我只要你實現任何代表(如cellForRow)你需要實現所有記憶......

要sumarize,我想做的事只能與1 TableView中完成並使用TableViewHeader,如果他們開始看到那些奇怪的消息即將到來,這就是我要做的和人們應該做的事情。

+0

「只要您實施任何代表......您需要全部實施它們」。不,這不是事實。如果指定'dataSource',則必須實現所需的方法,這些方法僅爲'numberOfRowsForSection'和'cellForRowAtIndexPath'。如果您有靜態表格視圖,則根本不應指定數據源。 – Rob