Các phần có thể thu gọn: [Khẳng định] Không thể xác định chỉ mục hàng toàn cầu mới cho preReloadFirstVisibleRow (0)


9

Tôi đang triển khai các tiêu đề phần có thể thu gọn trong UITableViewControll.

Đây là cách tôi xác định có bao nhiêu hàng để hiển thị trên mỗi phần:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    return self.sections[section].isCollapsed ? 0 : self.sections[section].items.count
}

Có một cấu trúc chứa thông tin phần với một bool cho 'isCollapsed'.

Đây là cách tôi chuyển đổi trạng thái của họ:

private func getSectionsNeedReload(_ section: Int) -> [Int]
{
    var sectionsToReload: [Int] = [section]

    let toggleSelectedSection = !sections[section].isCollapsed

    // Toggle collapse
    self.sections[section].isCollapsed = toggleSelectedSection

    if self.previouslyOpenSection != -1 && section != self.previouslyOpenSection
    {
        self.sections[self.previouslyOpenSection].isCollapsed = !self.sections[self.previouslyOpenSection].isCollapsed
        sectionsToReload.append(self.previouslyOpenSection)
        self.previouslyOpenSection = section
    }
    else if section == self.previouslyOpenSection
    {
        self.previouslyOpenSection = -1
    }
    else
    {
        self.previouslyOpenSection = section
    }

    return sectionsToReload
}



internal func toggleSection(_ header: CollapsibleTableViewHeader, section: Int)
{
    let sectionsNeedReload = getSectionsNeedReload(section)

    self.tableView.beginUpdates()
    self.tableView.reloadSections(IndexSet(sectionsNeedReload), with: .automatic)
    self.tableView.endUpdates()
}

Mọi thứ đều hoạt động và hoạt hình độc đáo, tuy nhiên trong bảng điều khiển khi thu gọn phần mở rộng, tôi nhận được [Khẳng định]:

[Khẳng định] Không thể xác định chỉ mục hàng toàn cầu mới cho preReloadFirstVisibleRow (0)

Điều này xảy ra, bất kể đó là Phần mở giống nhau, đóng (thu gọn) hoặc nếu tôi đang mở một phần khác và 'tự động đóng' phần mở trước đó.

Tôi không làm gì với dữ liệu; đó là cố chấp.

Bất cứ ai có thể giúp giải thích những gì còn thiếu? Cảm ơn


Là bàn của bạn được tạo thành từ một loạt các phần và không có nhiều hàng thực tế?
Byron Coetsee

Bạn đã bao giờ quản lý để sửa lỗi này?
PaulDoesDev

@ByronCoetsee Có, cho đến khi một phần được mở rộng. Vì vậy, khi tất cả sụp đổ, nó chỉ là phần tiêu đề. Khi một được mở rộng, tất cả các tiêu đề phần cho các phần không được mở rộng và tiêu đề của phần và sau đó là các ô cho dữ liệu.
iOSProgrammingIsFun

@PaulDoesDev Tôi đã làm, nhưng không sử dụng cơ chế này. Tôi hoàn toàn viết lại nó để trong khi nó xuất hiện giống nhau, nó hoạt động hoàn toàn khác nhau. Tuy nhiên tôi sẽ để cái này ở đây trong trường hợp ai đó có thể sửa cái này một cách tao nhã, hoặc nó giúp người khác bằng một cách nào đó.
iOSProgrammingIsFun

1
@iOSProgrammingIsFun haha yeah Tôi nghĩ rằng nó có thể cảm thấy giống như một hack và nó về mặt kỹ thuật, nhưng số lượng mã và thực tế là nó thực sự có nghĩa là khá sạch tôi có thể để cho bản thân mình ngủ vào ban đêm: Mã P đăng tải dưới đây
Byron Coetsee

Câu trả lời:


8

Để bảngView biết vị trí của nó trong khi nó tải lại các hàng, v.v., nó cố gắng tìm một "hàng neo" mà nó sử dụng làm tham chiếu. Điều này được gọi là a preReloadFirstVisibleRow. Vì bảngView này có thể không có bất kỳ hàng nào có thể nhìn thấy tại một số điểm vì tất cả các phần bị thu gọn, nên TableView sẽ bị lẫn lộn vì không thể tìm thấy một neo. Sau đó nó sẽ thiết lập lại đầu trang.

Giải pháp: Thêm một hàng có chiều cao 0 cho mỗi nhóm được thu gọn. Theo cách đó, ngay cả khi một phần được thu gọn, vẫn có một hàng hiện tại (mặc dù chiều cao 0px). TableView sau đó luôn có một cái gì đó để nối vào như một tài liệu tham khảo. Bạn sẽ thấy điều này có hiệu lực bằng cách thêm một hàng vào numberOfRowsInSectionnếu số hàng bằng 0 và xử lý bất kỳ indexPath.rowcuộc gọi nào khác bằng cách đảm bảo trả về giá trị ô phatom trước đó indexPath.rowlà cần thiết nếu datasource.visibleRowslà 0.

Việc giới thiệu mã dễ dàng hơn:

func numberOfSections(in tableView: UITableView) -> Int {
    return datasource.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return datasource[section].visibleRows.count == 0 ? 1 : datasource[section].visibleRows.count
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    datasource[section].section = section
    return datasource[section]
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if datasource[indexPath.section].visibleRows.count == 0 { return 0 }
    return datasource[indexPath.section].visibleRows[indexPath.row].bounds.height
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if datasource[indexPath.section].visibleRows.count == 0 { return UITableViewCell() }

    // I've left this stuff here to show the real contents of a cell - note how
    // the phantom cell was returned before this point.

    let section = datasource[indexPath.section]
    let cell = TTSContentCell(withView: section.visibleRows[indexPath.row])
    cell.accessibilityLabel = "cell_\(indexPath.section)_\(indexPath.row)"
    cell.accessibilityIdentifier = "cell_\(indexPath.section)_\(indexPath.row)"
    cell.showsReorderControl = true
    return cell
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.