접을 수있는 섹션 : [Assert] preReloadFirstVisibleRow에 대한 새 전역 행 인덱스를 확인할 수 없습니다 (0).


9

UITableViewController에서 접을 수있는 섹션 헤더를 구현하고 있습니다.

섹션 당 표시 할 행 수를 결정하는 방법은 다음과 같습니다.

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

'isCollapsed'에 대한 부울과 함께 섹션 정보를 보유하는 구조체가 있습니다.

상태를 전환하는 방법은 다음과 같습니다.

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()
}

확장 된 섹션을 축소 할 때 콘솔에서 모든 것이 잘 작동하고 애니메이션 효과를줍니다. [Assert]는 다음과 같습니다.

[Assert] preReloadFirstVisibleRow에 대한 새 전역 행 인덱스를 확인할 수 없습니다 (0).

이것은 동일한 열린 섹션인지 여부에 관계없이 (닫기) 또는 다른 섹션을 열고 이전에 열린 섹션을 '자동 닫기'하는지에 관계없이 발생합니다.

나는 데이터와 관련이 없다. 영구적입니다.

누락 된 내용을 설명하는 사람이 있습니까? 감사


테이블 뷰는 많은 섹션으로 구성되어 있으며 실제 행은 많지 않습니까?
바이런 Coetsee '11

이 문제를 해결 한 적이 있습니까?
PaulDoesDev

섹션이 확장 될 때까지 @ByronCoetsee 예. 따라서 모두 축소되면 섹션 헤더 일뿐입니다. 하나가 확장되면 확장되지 않은 섹션의 모든 섹션 헤더이고 섹션 헤더와 데이터의 셀입니다.
iOS 프로그래밍 IsFun

@PaulDoesDev 내가 한 것이지만이 메커니즘을 사용하지는 않습니다. 나는 그것이 똑같이 보일 때 완전히 다르게 작동합니다. 그러나 누군가 이것을 우아하게 고칠 수 있거나 어떤 식 으로든 다른 사람들을 도울 수 있도록 여기에 남겨 두겠습니다.
iOS 프로그래밍 IsFun

1
그래 하하 @iOSProgrammingIsFun 나는 그것이 해킹처럼 느낄 수 있습니다 생각은 기술적으로하지만, 내가 할 수있는 코드의 양과 실제로 꽤 깨끗한 수단이 있다는 사실은 자신이 밤에 잠을 : P 코드는 아래 게시
바이런 Coetsee을

답변:


8

tableView가 행 등을 다시로드하는 동안 어디에 있는지 알기 위해 참조로 사용하는 "앵커 행"을 찾습니다. 이것을이라고합니다 preReloadFirstVisibleRow. 모든 섹션이 축소되어이 tableView에 특정 시점에 표시되는 행이 없을 수 있으므로 tableView는 앵커를 찾을 수 없으므로 혼동됩니다. 그런 다음 상단으로 재설정됩니다.

솔루션 : 축소 된 모든 그룹에 0 높이 행을 추가하십시오. 이렇게하면 섹션이 축소 되어도 여전히 행이 있습니다 (높이는 0px 임). 그런 다음 tableView에는 항상 참조로 연결할 항목이 있습니다. 당신의 행의 추가에 의해 영향이 표시됩니다 numberOfRowsInSection행 개수가 0이고 더 이상 처리 할 경우 indexPath.row이전 phatom의 셀 값 반환 확인하여 통화 indexPath.row(가) 경우 필요한 datasource.visibleRows0입니다.

코드로 데모하기가 더 쉽습니다.

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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.