heightForHeaderInSection中未捕获的异常

时间:2015-02-19 20:49:10

标签: ios uitableview swift

我收到以下错误,尝试设计首选项tableview。

    2015-02-19 21:19:49.204 MyApp[8337:285561] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000110859b95 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001123aebb7 objc_exception_throw + 45
    2   CoreFoundation                      0x00000001107501fe -[__NSArrayI objectAtIndex:] + 190
    3   UIKit                               0x000000011161df2a -[UITableViewDataSource tableView:heightForHeaderInSection:] + 39
    4   UIKit                               0x00000001111f0e58 -[UITableView _delegateWantsHeaderForSection:] + 261
    5   UIKit                               0x000000011137b183 -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 162
    6   UIKit                               0x0000000111381645 -[UITableViewRowData rectForFooterInSection:heightCanBeGuessed:] + 320
    7   UIKit                               0x000000011138173a -[UITableViewRowData heightForTable] + 56
    8   UIKit                               0x00000001111cd870 -[UITableView _updateContentSize] + 381
    9   UIKit                               0x00000001111ec5a3 -[UITableView setContentInset:] + 336
    10  UIKit                               0x000000011121e6ef -[UIViewController _setNavigationControllerContentInsetAdjustment:] + 501
    11  UIKit                               0x000000011eb19b89 -[UIViewControllerAccessibility _setNavigationControllerContentInsetAdjustment:] + 80
    12  UIKit                               0x00000001112541a6 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 432
    13  UIKit                               0x0000000111254323 -[UINavigationController _layoutViewController:] + 116
    14  UIKit                               0x0000000111254825 -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 216
    15  UIKit                               0x0000000111249957 -[UINavigationController _startCustomTransition:] + 1657
    16  UIKit                               0x000000011125567f -[UINavigationController _startDeferredTransitionIfNeeded:] + 386
    17  UIKit                               0x00000001112561ce -[UINavigationController __viewWillLayoutSubviews] + 43
    18  UIKit                               0x000000011139eded -[UILayoutContainerView layoutSubviews] + 202
    19  UIKit                               0x000000011eb3351e -[UILayoutContainerViewAccessibility layoutSubviews] + 43
    20  UIKit                               0x0000000111176040 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
    21  QuartzCore                          0x0000000114c2c38a -[CALayer layoutSublayers] + 146
    22  QuartzCore                          0x0000000114c20c46 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
    23  QuartzCore                          0x0000000114c20ab6 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
    24  QuartzCore                          0x0000000114b8cf1a _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
    25  QuartzCore                          0x0000000114b8e0a5 _ZN2CA11Transaction6commitEv + 447
    26  QuartzCore                          0x0000000114b8e73f _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
    27  CoreFoundation                      0x000000011078cd27 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    28  CoreFoundation                      0x000000011078cc80 __CFRunLoopDoObservers + 368
    29  CoreFoundation                      0x0000000110782ab3 __CFRunLoopRun + 1123
    30  CoreFoundation                      0x00000001107823e6 CFRunLoopRunSpecific + 470
    31  GraphicsServices                    0x0000000114512a3e GSEventRunModal + 161
    32  UIKit                               0x00000001110f5b60 UIApplicationMain + 1282
    33  MyApp                 0x000000010fe687f7 main + 135
    34  libdyld.dylib                       0x0000000112b52145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

我建议,tableView:heightForHeaderInSection中的某些东西搞砸了,但我无法猜测那里发生了什么。

以下是其他相关课程: PreferencesTableViewController

import UIKit

class PreferencesTableViewController: UITableViewController {

    let factory = PreferencesCellFactory()

    override func viewDidLoad() {
        super.viewDidLoad()
        factory.setTitleForSection(0, title: "Off")
        factory.createSwitcherCell("Fallback-Modus", subtitle: "No-Subtitle")
        factory.createEditorCell("Shortname", subtitle: "Shortname") 


        factory.setTitleForSection(1, title: "New")
        //factory.createEditorCell("New Testcell", subtitle: "Hallo", section: 1)

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }

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

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return factory.numberOfSections()

    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return factory.numberOfRowsInSection(section)
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
        return factory.getCellForSectionWithIndex(SectionNr: indexPath.section, index: indexPath.row) // returns correct cell
    }

    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return factory.getTitleForSection(SectioNr: section) // returns correct header
    }


}

PreferencesCellFactory

import Foundation

class PreferencesCellFactory {
    var sections : [[UITableViewPreferencesCell]]
    var sectionTitles : [String]

    init() {
        sections        = [[UITableViewPreferencesCell]]()
        sectionTitles   = [String]()
    }

    func numberOfSections() -> Int {
        return sections.count
    }


    func numberOfRowsInSection(section: Int) -> Int{
        return sections[section].count
    }


    func setTitleForSection(index: Int, title: String!){
        if sectionTitles.count == index {
            sectionTitles.append(title)
        }
        else {
         sectionTitles[index] = title
        }
    }



    func createEditorCell(title: String, subtitle: String){
        createEditorCell(title, subtitle: subtitle, section: 0)
    }


    func createEditorCell(title: String, subtitle: String, section: Int){


        if sections.count == section {
            sections.append([UITableViewPreferencesCell]())
        }

        let cell = UITableViewEditorCell()
        cell.textLabel?.text         = title
        cell.detailTextLabel?.text   = subtitle
        sections[section].append(cell)
        println("Test")
    }


    func createSwitcherCell(title: String, subtitle: String){
        createSwitcherCell(title, subtitle: subtitle, section: 0)
    }


    func createSwitcherCell(title: String, subtitle: String, section: Int){
        // Wenn noch keine Sections angelegt sind, muss erst eine initialisiert werden
        if sections.count == 0 {
            sections.append([UITableViewPreferencesCell]())
        }

        let cell = UITableViewSwitcherCell()
        cell.textLabel?.text         = title
        cell.detailTextLabel?.text   = subtitle
        sections[section].append(cell)
    }



    func getCellAtIndex(index: Int) -> UITableViewPreferencesCell{
        if sections.count == 0 {
            NSLog("Sections Array ist leer")
        }
        return getCellForSectionWithIndex(SectionNr: 0, index: index)
    }



    func getCellForSectionWithIndex(SectionNr section: Int, index: Int) -> UITableViewPreferencesCell{
        if sections.count == 0 {
            NSLog("Sections Array ist leer")
        }
        return sections[section][index]
    }




    func getCells() -> [UITableViewPreferencesCell]{
        if sections.count == 0 {
            NSLog("Sections Array ist leer")
        }
        return getCellsForSection(SectionNr: 0)
    }



    func getCellsForSection(SectionNr section: Int) -> [UITableViewPreferencesCell]{
        if sections.count == 0 {
            NSLog("Sections Array ist leer")
        }
        return sections[section]
    }



    func getTitleForSection(SectioNr section: Int) -> String {
        if sectionTitles.count == 0 {
           NSLog("SectionTitles Array ist leer")
            return "Not titles found"
        }
        return sectionTitles[section]
    }
}

我希望任何人都可以提供帮助。如有必要,我可以提供更多细节。

提前致谢

P.S。:如果numberOfSectionsInTableView返回1.则不会发生错误

解决方案的第一步:

我添加了所有这些方法,现在它似乎按预期工作,但为什么我必须实现它们?

override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50.0
    }

    override func tableView(tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
        return 50.0
    }

    override func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 50.0
    }

    override func tableView(tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat {
        return 50.0
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 50.0
    }

    override func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int {
        return 0
    }
    override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView()
    }
    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return UIView()
    }

2 个答案:

答案 0 :(得分:1)

你在这部分的问题:

func getTitleForSection(SectioNr section: Int) -> String {
        if sectionTitles.count == 0 {
           NSLog("SectionTitles Array ist leer")
            return "Not titles found"
        }
        return sectionTitles[section]
    }
正如您在错误日志中看到的那样,它出现在[__NSArrayI objectAtIndex:]中 因此,如果您sectionTitles数组有一个元素,并且您询问1-st,2-nd或更大的索引,那么您的应用程序将抛出异​​常(并且粉碎)。在执行sectionTitles[section]

之前,您应该检查此数组中的对象数

UPD:

我对您的代码有疑问:

sectionsPreferencesCellFactory的{​​{1}}类型UITableViewPreferencesCell(当然是自定义类),但您为sections[section].append(cell)做了下标。你是否实现了它以及它的外观?

因为没有它我无法重现代码,如果我评论它,那么应用程序不会粉碎。

答案 1 :(得分:1)

问题是在桌面视图中使用静态单元格。这意味着,必须实施所有提到的方法。切换回动态单元可以毫无问题地解决问题。

如果使用静态单元格,则必须实现所有查看属性,如headerView等。