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.