簡體   English   中英

"檢測 UITableView 部分標題何時捕捉到屏幕頂部"

[英]Detect when UITableView section header snaps to the top of the screen

我想檢測UITableView部分標題何時捕捉到屏幕頂部,然后修改標題的高度,但我不知道該怎么做。 任何人都可以幫忙嗎?

通過使用didEndDisplayingHeaderViewwillDisplayHeaderView委托方法,我能夠完成檢測哪個標題卡在表格視圖的頂部。 這里的想法是,當我們滾動表格視圖的各個部分時,標題周圍的行變得可見,我們可以使用tableView.indexPathsForVisibleRows獲取所有可見行的索引路徑。 根據我們是向上還是向下滾動,我們將屏幕上的第一個或最后一個 indexPath 與剛剛出現/消失的視圖的索引路徑進行比較。

//pushing up
func tableView(_ tableView: UITableView,
               didEndDisplayingHeaderView view: UIView,
               forSection section: Int) {

    //lets ensure there are visible rows.  Safety first!
    guard let pathsForVisibleRows = tableView.indexPathsForVisibleRows,
        let lastPath = pathsForVisibleRows.last else { return }

    //compare the section for the header that just disappeared to the section
    //for the bottom-most cell in the table view
    if lastPath.section >= section {
        print("the next header is stuck to the top")
    }

}

//pulling down
func tableView(_ tableView: UITableView,
               willDisplayHeaderView view: UIView,
               forSection section: Int) {

    //lets ensure there are visible rows.  Safety first!
    guard let pathsForVisibleRows = tableView.indexPathsForVisibleRows,
        let firstPath = pathsForVisibleRows.first else { return }

    //compare the section for the header that just appeared to the section
    //for the top-most cell in the table view
    if firstPath.section == section {
        print("the previous header is stuck to the top")
    }
}

我去把我的評論變成代碼,它的工作原理如下:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {

    if scrollView == yourTableView {
        if yourTableView.rectForHeader(inSection: <#sectionIWant#>).origin.y <= tableView.contentOffset.y-defaultOffSet.y &&
            yourTableView.rectForHeader(inSection: <#sectionIWant#>+1).origin.y > tableView.contentOffset.y-defaultOffSet.y {
            print("Section Header I want is at top")
        }
    } else {
        //Handle other scrollViews here
    }
}

所以,你替換sectionIWantInt ,當該節的頭是在頂部時, print將run.Note是yourTableView不是參數scrollViewDidScroll所以你必須參考存到自己UITableView的其他地方,並在這里使用它。

或者,如果您想不斷更新哪個部分標題位於頂部,您可以使用:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {

    if scrollView == yourTableView {
        var currentSection = 0
        while !(tableView.rectForHeader(inSection: currentSection).origin.y <= (tableView.contentOffset.y-defaultOffSet.y) &&
            tableView.rectForHeader(inSection: currentSection+1).origin.y > (tableView.contentOffset.y)-defaultOffSet.y) {
                if tableView.contentOffset.y <= tableView.rectForHeader(inSection: 0).origin.y {
                    break   //Handle tableView header - if any
                }
                currentSection+=1
                if currentSection > tableView.numberOfSections-2 {
                    break   //Handle last section
                }
        }
        print(currentSection)
    }

}

請注意,在兩個代碼中都有一個defaultOffSet ,它是加載時tableViewcontentOffSet ,這是考慮到contentOffSet在某些情況下不會從 0 開始 - 我不確定何時但我之前確實遇到過這種情況。

這個解決方案對我有用。

func scrollViewDidScroll(_ scrollView: UIScrollView) {
  self.visibleHeaders.forEach { header in
    let headerOriginalFrame = self.myTableView.rectForHeader(inSection: header.tag)
    let headerCurrentFrame = header.frame
    let fixed = headerOriginalFrame != headerCurrentFrame
    // Do things you want
  }
}

這是完整的源代碼。 https://github.com/jongwonwoo/CodeSamples/blob/master/TableView/TableviewFixedHeader/Tableview/ViewController.swift

事實證明,我對這個問題的解決方案確實有效且用途廣泛。 如果這對某人有幫助,我會很高興

func scrollViewDidScroll(_ scrollView: UIScrollView) {
let sectionPosition = tableView.rect(forSection: sectionIndex)
let translation = scrollView.panGestureRecognizer.translation(in: scrollView.superview)

if let dataSource = dataSource,
   scrollView.contentOffset.y >= sectionPosition.minY {

//Next section

    guard dataSource.count - 1 > sectionIndex else { return }
    sectionIndex += 1
} else if translation.y > 0,
          scrollView.contentOffset.y <= sectionPosition.minY {

//Last section

    guard sectionIndex > 0 else { return }
    sectionIndex -= 1
}

派對遲到了,但查看所有回復並沒有解決我的問題。

下面的做法,每一個都借鑒了一點,同時又增加了一個更通用且不固定的做法。

    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard let visibleIndexs = self.tableView.indexPathsForVisibleRows,
              !visibleIndexs.isEmpty else { return }
        
        var visibleHeaders = [Int]()
        visibleIndexs.forEach { anIndexPath in
            if !visibleHeaders.contains(anIndexPath.section) {
                visibleHeaders.append(anIndexPath.section)
            }
        }
        
        visibleHeaders.forEach { header in
            let headerView = tableView.headerView(forSection: header)
            let headerOriginalFrame = self.tableView.rectForHeader(inSection: header)
            if headerOriginalFrame != headerView?.frame {
    //do something with top headerView
            } else {
    //do something else with all the others headerView(s)
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM