UITableView-맨 위로 스크롤


393

내 테이블보기에서 맨 위로 스크롤해야합니다. 그러나 첫 번째 객체가 섹션 0, 행 0이 될 것이라고 보장 할 수는 없습니다. 테이블 뷰가 섹션 번호 5에서 시작될 수 있습니다.

그래서 전화하면 예외가 발생합니다.

[mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];

테이블 뷰의 상단으로 스크롤하는 다른 방법이 있습니까?

답변:


856

UITableView는 UIScrollView의 하위 클래스이므로 다음을 사용할 수도 있습니다.

[mainTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];

또는

[mainTableView setContentOffset:CGPointZero animated:YES];

그리고 스위프트에서 :

mainTableView.setContentOffset(CGPointZero, animated:true)

그리고 스위프트 3 이상에서 :

mainTableView.setContentOffset(.zero, animated: true)

9
먼저 CGRectMero (0, 0, 0, 0)에 해당하는 CGRectZero로 이것을 시도했습니다. 이것은 작동하지 않지만 이상하게도 이상합니다. 양의 너비와 높이가 필요하다고 생각합니다. 감사합니다.
Keller

5
참고, 당신이 원하는 것입니다 애니메이션을 : NO 이이 scrollToRowAtIndexPath에서 실행하는 경우 : 올바른 위치에 테이블 출발을 할 수 있도록한다. 그것이 도움이되기를 바랍니다!
Fattie

3
@ hasan83 CGRectMake (0, 0, 0, 0) 또는 CGRectZero는 보이는 사각형이 아닙니다. 또한 [mainTableView setContentOffset : CGPointZero animated : YES]; 더 예쁜 표현입니다.
catlan

8
누구나 iOS11 에서이 모든 것이 깨져서 어떤 경우에는 올바르게 스크롤되지 않는다는 것을 알았습니다.
피터 라피 수

11
@PeterLapisu self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: UITableViewScrollPosition.top, animated: true)는 iOS 11에서 작동하는 것 같습니다
Jordan S

246

참고 :이 답변은 iOS 11 이상에서는 유효하지 않습니다.

나는 선호한다

[mainTableView setContentOffset:CGPointZero animated:YES];

테이블 뷰에 상단 삽입물이 있으면 빼야합니다.

[mainTableView setContentOffset:CGPointMake(0.0f, -mainTableView.contentInset.top) animated:YES];

12
토마토, 토마토. 흠 ... 글씨가 명확하게 나오지 않습니다.
FreeAsInBeer 2

14
테이블 머리글 또는 바닥 글보기가 있고이를 포함 할 때 사용하는 가장 좋은 방법입니다.
mafonya

6
이것은 실제로 명확한 코드이지만 맨 위에서 tableView0이 아닌 경우 작동하지 않습니다 contentInset. 예를 들면 다음과 같습니다 tableView.contentInset = UIEdgeInsetsMake(5.0f, 0.0f, 250.0f, 0.0f);.. 이 경우 코드에서로 tableView스크롤합니다 (0.0f, 5.0f).
tolgamorf

25
내 이전 의견에 대한 해결책 :[tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];
tolgamorf

3
iOS 11에서는 -scrollView.adjustedContentInset.top대신 사용하는 것이 좋습니다.
Marián Černý

79

가능한 조치 :

1

func scrollToFirstRow() {
    let indexPath = NSIndexPath(forRow: 0, inSection: 0)
    self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
}

2

func scrollToLastRow() {
    let indexPath = NSIndexPath(forRow: objects.count - 1, inSection: 0)
    self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true)
}

func scrollToSelectedRow() {
    let selectedRows = self.tableView.indexPathsForSelectedRows
    if let selectedRow = selectedRows?[0] as? NSIndexPath {
        self.tableView.scrollToRowAtIndexPath(selectedRow, atScrollPosition: .Middle, animated: true)
    }
}

4

func scrollToHeader() {
    self.tableView.scrollRectToVisible(CGRect(x: 0, y: 0, width: 1, height: 1), animated: true)
}

5

func scrollToTop(){
    self.tableView.setContentOffset(CGPointMake(0,  UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
}

맨 위로 스크롤 비활성화 :

func disableScrollsToTopPropertyOnAllSubviewsOf(view: UIView) {
    for subview in view.subviews {
        if let scrollView = subview as? UIScrollView {
            (scrollView as UIScrollView).scrollsToTop = false
        }
        self.disableScrollsToTopPropertyOnAllSubviewsOf(subview as UIView)
    }
}

요구 사항에 따라 수정하여 사용하십시오.

스위프트 4

  func scrollToFirstRow() {
    let indexPath = IndexPath(row: 0, section: 0)
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
  }

그 해결책은 완벽합니다-scrollToFirstRow
Mehul

훌륭한 요약. 섹션 헤더가 있으면 option4 scrollToHeader를 사용해야합니다.
Vincent

Tableview 위에있는 검색 창으로 스크롤하는 방법이 있습니까?
Tyler Rutt

27

NSIndexPath (빈 테이블)를 사용하지 않는 것이 좋으며 상단 포인트가 CGPointZero (콘텐츠 삽입)라고 가정하는 것이 좋습니다.

[tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];

도움이 되었기를 바랍니다.


더 이상 유효 아이폰 OS (11)의 등
rmaddy

21

스위프트 4 :

이것은 매우 잘 작동합니다.

//self.tableView.reloadData() if you want to use this line remember to put it before 
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)

3
tableView에 tableHeaderView가 있고 인라인 인 경우 (내용과 함께 스크롤)
finneycanhelp

1
나는 평범하고 a UITableViewStyleGrouped(헤더가 내용으로 스크롤 됨)를 가지고 있으며이 코드가 작동합니다. 메인 스레드에 있는지 확인하고보기가 나타난 후이 코드를 시작하십시오 ( viewDidAppear). 여전히 문제가있는 경우 코드를 다음과 같이 입력하십시오 :DispatchQueue.main.asyncAfter(deadline: .now()+0.1, execute: { // the code }
Alessandro Ornano

1
감사합니다. 첫 번째 셀로 이동합니다. 그러나 테이블 뷰 헤더는 표시되지 않습니다.
finneycanhelp

어떤 이유로 tableView가 비어 있으면 (0 행에 0 섹션에 셀이 없음)
Maxim Skryabin

17

empty에서 일부 메소드를 시도하는 중 문제가 발생했습니다 tableView. 빈 테이블 뷰를 처리하는 Swift 4의 또 다른 옵션이 있습니다.

extension UITableView {
  func hasRowAtIndexPath(indexPath: IndexPath) -> Bool {
    return indexPath.section < self.numberOfSections && indexPath.row < self.numberOfRows(inSection: indexPath.section)
  }

  func scrollToTop(animated: Bool) {
    let indexPath = IndexPath(row: 0, section: 0)
    if self.hasRowAtIndexPath(indexPath: indexPath) {
      self.scrollToRow(at: indexPath, at: .top, animated: animated)
    }
  }
}

용법:

// from yourViewController or yourTableViewController
tableView.scrollToTop(animated: true)//or false

이것은 테이블 헤더 또는 섹션 헤더를 설명하지 않습니다.
rmaddy 5

16

사용 금지

 tableView.setContentOffset(.zero, animated: true)

때때로 오프셋을 잘못 설정할 수 있습니다. 예를 들어 필자의 경우 셀은 실제로 안전 영역이 삽입 된 뷰보다 약간 위에있었습니다. 안좋다.

철저한 사용

 tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)

1
완벽한 솔루션.
Baby Groot

정확히 내가 찾던 것은 고마워.
Simon

이러한 솔루션 중 어느 것도 유효하지 않습니다. 첫 번째는 iOS 11 이상에서 작동하지 않습니다. 테이블 뷰에 테이블 헤더가 있거나 첫 번째 섹션에 섹션 헤더가 있으면 두 번째 행이 작동하지 않습니다. 첫 번째 행을 맨 위에 놓고 헤더를 표시하지 않아도됩니다.
rmaddy 5

@rmaddy 최고의 솔루션은 무엇입니까?
ScottyBlades

15

iOS 11에서는 adjustedContentInset통화 중 상태 표시 줄이 표시되는지 여부에 따라 두 경우 모두 상단으로 올바르게 스크롤하는 데 사용 하십시오.

if (@available(iOS 11.0, *)) {
    [tableView setContentOffset:CGPointMake(0, -tableView.adjustedContentInset.top) animated:YES];
} else {
    [tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:YES];
}

빠른:

if #available(iOS 11.0, *) {
    tableView.setContentOffset(CGPoint(x: 0, y: -tableView.adjustedContentInset.top), animated: true)
} else {
    tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)
}

12

가있는 테이블의 contentInset경우 내용 오프셋을 설정하면 CGPointZero작동하지 않습니다. 콘텐츠 상단으로 스크롤하고 테이블 상단으로 스크롤합니다.

콘텐츠 삽입을 고려하면 다음과 같이 생성됩니다.

[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:NO];

1
감사합니다. CGPointZero로 계속 설정했는데 왜 이런 일이 발생했는지 이해할 수 없었습니다.
johnrechd

더 이상 유효 아이폰 OS (11)의 등
rmaddy

10

이 코드를 사용하면 특정 섹션을 맨 위로 스크롤 할 수 있습니다

CGRect cellRect = [tableinstance rectForSection:section];
CGPoint origin = [tableinstacne convertPoint:cellRect.origin 
                                    fromView:<tableistance>];
[tableinstance setContentOffset:CGPointMake(0, origin.y)];

이것은 가장 간단한 코드였으며 정상적으로 작동했습니다. 실제로 CGPointMake (0.0f, 0.0f)를 넣었습니다. 건배!
Felipe

이 코드는 섹션을 위로 스크롤하는 데 매우 유용합니다.
srinivas n


8

스위프트 3

tableView.setContentOffset(CGPoint.zero, animated: true)

작동 tableView.setContentOffset하지 않으면.

사용하다:

tableView.beginUpdates()
tableView.setContentOffset(CGPoint.zero, animated: true)
tableView.endUpdates()

1
iOS 11 이상에서는 유효하지 않습니다.
rmaddy 5

7

tableView모든 종류의 삽입물로 가득 차 있기 때문에 이것이 유일하게 효과적이었습니다.

스위프트 3

if tableView.numberOfSections > 0 && tableView.numberOfRows(inSection: 0) > 0 {
  tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}

스위프트 2

if tableView.numberOfSections > 0 && tableView.numberOfRowsInSection(0) > 0 {
  tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
}

이것은 나에게 더 유용했다
Tejzeratul

좋은 답변, 감사합니다
Jeremy Bader

7

이미 말한 것에 덧붙여, 확장 (Swift) 또는 카테고리 (Objective C)를 작성하여 나중에 이것을 쉽게 할 수 있습니다.

빠른:

extension UITableView {
    func scrollToTop(animated: Bool) {
        setContentOffset(CGPointZero, animated: animated)
    }
}

주어진 tableView를 맨 위로 스크롤 할 때마다 다음 코드를 호출 할 수 있습니다.

tableView.scrollToTop(animated: true)

2
더 이상 유효 아이폰 OS (11)의 등
rmaddy

6

삽입물을 고려할 때 다음을 선호합니다. 삽입물이 없으면 삽입물이 0이므로 여전히 맨 위로 스크롤됩니다.

tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)

더 이상 유효 아이폰 OS (11)의 등
rmaddy

5

빠른 :

tableView 헤더가없는 경우 :

tableView.setContentOffset(CGPointMake(0,  UIApplication.sharedApplication().statusBarFrame.height ), animated: true)

그렇다면 :

tableView.setContentOffset(CGPointMake(0, -tableViewheader.frame.height   + UIApplication.sharedApplication().statusBarFrame.height ), animated: true)

5

스위프트 5, iOS 13

나는이 질문에 이미 많은 답변이 있지만 내 경험에 따르면 항상 작동하는 방법은 하나뿐입니다.

tableView.scrollToRow(at: IndexPath(row: someArray.count - 1, section: 0), at: .bottom, animated: true)

키보드로 움직이는 애니메이션 등의 테이블에서 작업하는 경우 다른 답변은 종종 절대 하단이 아닌 거의 하단으로 스크롤됩니다 . 이 방법을 사용하면 매번 테이블의 절대 끝을 얻을 수 있습니다.


당신은 또한 섹션이 있는지 확인해야합니다
Onur Tuna

4

iOS 11에서 올바르게 작동하는 데 사용하는 내용은 다음과 같습니다.

extension UIScrollView {
    func scrollToTop(animated: Bool) {
        var offset = contentOffset
        if #available(iOS 11, *) {
            offset.y = -adjustedContentInset.top
        } else {
            offset.y = -contentInset.top
        }
        setContentOffset(offset, animated: animated)
    }
}

4

스위프트 5에서는 @Adrian의 답변에 감사드립니다.

extension UITableView{

    func hasRowAtIndexPath(indexPath: IndexPath) -> Bool {
        return indexPath.section < numberOfSections && indexPath.row < numberOfRows(inSection: indexPath.section)
    }

    func scrollToTop(_ animated: Bool = false) {
        let indexPath = IndexPath(row: 0, section: 0)
        if hasRowAtIndexPath(indexPath: indexPath) {
            scrollToRow(at: indexPath, at: .top, animated: animated)
        }
    }

}

용법:

tableView.scrollToTop()

2
1. 이것은 Swift 4에서도 유효합니다. 2. 테이블 헤더 나 섹션 헤더가있는 경우 작동하지 않습니다.
rmaddy 5

3

contentOffset을 사용하는 것이 올바른 방법이 아닙니다. 이것은 테이블 뷰의 자연스러운 방식이므로 더 좋습니다.

tableView.scrollToRow(at: NSIndexPath.init(row: 0, section: 0) as IndexPath, at: .top, animated: true)

2
테이블 머리글이나 섹션 머리글이 있으면 작동하지 않습니다.
rmaddy

3

이것은 나를 위해 일한 유일한 코드 스 니펫이었습니다.

스위프트 4 :

    tableView.scrollRectToVisible(CGRect(x: 0, y: 0, width: 1, height: 1), animated: true)
    tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
    tableView.setContentOffset(CGPoint(x: 0, y: -70), animated: true)

PS 70은 헤더 및 테이블 뷰 셀의 높이입니다.


이것은 맨 위로 스크롤하는 올바른 방법과는 거리가 멀습니다. 콘텐츠 오프셋을 설정하기 위해 세 개의 개별 라인을 사용하는 것은 의미가 없습니다. 마지막 줄만 필요하지만 특정 오프셋을 하드 코딩하는 것이 올바른 해결책이 아닙니다.
rmaddy 5

2
func scrollToTop() {
        NSIndexPath *topItem = [NSIndexPath indexPathForItem:0 inSection:0];
        [tableView scrollToRowAtIndexPath:topItem atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

UITableView를 맨 위로 스크롤하려는 경우이 함수를 호출하십시오.


2

확장을 통한 Swift 4 는 빈 테이블 뷰를 처리합니다.

extension UITableView {
    func scrollToTop(animated: Bool) {
        self.setContentOffset(CGPoint.zero, animated: animated);
    }
}

이것은 iOS 11
rmaddy

2

나는 tabBarController를 사용하고 모든 탭에서 테이블 뷰에 몇 개의 섹션이 있으므로 이것이 최선의 해결책입니다.

extension UITableView {

    func scrollToTop(){

        for index in 0...numberOfSections - 1 {
            if numberOfSections > 0 && numberOfRows(inSection: index) > 0 {
                scrollToRow(at: IndexPath(row: 0, section: index), at: .top, animated: true)
                break
            }

            if index == numberOfSections - 1 {
                setContentOffset(.zero, animated: true)
                break
            }
        }

    }

}

1

-1 *상태 표시 줄과 탐색 표시 줄의 합계에 곱하기를 추가해야 했습니다. 화면에서 높이가 높아지기 때문에

self.tableView.setContentOffset(CGPointMake(0 , -1 * 
  (self.navigationController!.navigationBar.height +  
  UIApplication.sharedApplication().statusBarFrame.height) ), animated:true)

1

신속하게

행 = selectioncellRowNumber 섹션이있는 경우 섹션 = selectionNumber 설정하지 않은 경우 0은

//UITableViewScrollPosition.Middle 또는 Bottom 또는 Top

var lastIndex = NSIndexPath(forRow:  selectioncellRowNumber, inSection: selectionNumber)
self.tableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Middle, animated: true)

1

프로그래밍 방식으로 위쪽으로 스크롤하는 코드는 다음과 같습니다.

빠른:

self.TableView.setContentOffset(CGPointMake(0, 1), animated:true)

1

스위프트 -3에서 :

self.tableView.setContentOffset(CGPoint.zero, animated: true)

0

표에서 스크롤 애니메이션을 이동하려면이 코드를 사용하십시오. 스크롤은 0.5 초 안에 애니메이션과 함께 맨 위로 이동합니다.

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

[_tableContent scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];

[UIView commitAnimations];

0

스위프트로 :

self.scripSearchView.quickListTbl?.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.