UIScrollView를 가져 와서 맨 위로 스크롤


답변:


316

iOS 7 업데이트

[self.scrollView setContentOffset:
    CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];

실물

[self.scrollView setContentOffset:CGPointZero animated:YES];

또는 가로 스크롤 위치를 유지하고 세로 위치 만 재설정하려는 경우 :

[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0)
    animated:YES];

50
iOS 7에서이 작업을 수행하는 경우 UIScrollView contentInset불행하게도 를 고려해야합니다 . [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];않는 나를 위해 일
runmad

11
탐색 및 상태 표시 줄 바로 아래에서 맨 위로 스크롤 할 수있었습니다. [scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:YES];그것은 iOS 6 & 7에서 작동
Amozoss

스프라이트 키트의 반전 된 견해로 미쳤던 일을하고 있기 때문에 이것은 나를 위해 작동하지 않았습니다. 그러나 다른 사람이 나만큼 미쳤다면-스크롤 [scrollView setContentOffset:CGPointMake(0, scrollView.contentSize.height-scrollView.frame.size.height) animated:YES];

최신 코멘트 : OS 버전에 관계없이 컨텐츠 삽입을 조정해야합니다. iOS 7은 상태 표시 줄 아래로 스크롤 내용을 허용하는 데 사용되지만 항상 속성으로 노출되므로 누군가가 항상 사용할 수 있습니다.
Tommy

2
iOS 11 이상의 경우 조정 된 콘텐츠 삽입을 사용한 Jakub Truhlář의 답변은 적어도 제 경우에는 도움이되었습니다.
tnev

61

다음은 쉽게 사용할 수있는 Swift 확장입니다.

extension UIScrollView {
    func scrollToTop() {
        let desiredOffset = CGPoint(x: 0, y: -contentInset.top)
        setContentOffset(desiredOffset, animated: true)
   }
}

용법:

myScrollView.scrollToTop()

40

iOS 11 이상

새로운 작업을 시도하십시오 adjustedContentInset.

예를 들어 (위로 스크롤) :

var offset = CGPoint(
    x: -scrollView.contentInset.left, 
    y: -scrollView.contentInset.top)

if #available(iOS 11.0, *) {
    offset = CGPoint(
        x: -scrollView.adjustedContentInset.left, 
        y: -scrollView.adjustedContentInset.top)    
}

scrollView.setContentOffset(offset, animated: true)

당신이 사용하는 경우에도 prefersLargeTitles, safe area



23

사용하다 setContentOffset:animated:

[scrollView setContentOffset:CGPointZero animated:YES];

17

Swift 2.0 / 3.0 / 4.0 및 iOS 7+에 대한 답변 :

let desiredOffset = CGPoint(x: 0, y: -self.scrollView.contentInset.top)
self.scrollView.setContentOffset(desiredOffset, animated: true)

8

iOS7에서는 iOS6에서 작동하는 특정 스크롤보기를 맨 위로 가져 오는 데 어려움이 있었고 이것을 사용하여 스크롤보기를 맨 위로 이동했습니다.

[self.myScroller scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];

iOS7에서도 동일한 문제가 있습니다. 누구나 UITableView에 대해 이것을 활성화하는 방법을 알고 있습니까?
DZenBot

1
애니메이션이 아니요 일 때 작동하는 방식이 재미 있지만 애니메이션이 예일 때는 작동하지 않습니다. YES 인 경우 거의 topdevgm16으로 스크롤됩니다.
Matt Becker


2

상태 표시 줄 scrollToTop 동작을 완전히 복제하려면 contentOffset을 설정해야 할뿐만 아니라 scrollIndicators가 표시되도록해야합니다. 그렇지 않으면 사용자가 빨리 길을 잃을 수 있습니다.

이것을 달성하는 유일한 공개 방법은 flashScrollIndicators입니다. 불행하게도 contentOffset을 설정 한 후 한 번 호출하면 즉시 재설정되므로 아무런 효과가 없습니다. 에서 플래시를 할 때마다 작동한다는 것을 알았습니다 scrollViewDidScroll:.

// define arbitrary tag number in a global constants or in the .pch file
#define SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG 19291

- (void)scrollContentToTop {
    [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];

    self.scrollView.tag = SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.scrollView.tag = 0;
    });
}

UIScrollViewDelegate (또는 UITable / UICollectionViewDelegate)에서 다음을 구현하십시오.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.tag == SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG) {
        [scrollView flashScrollIndicators];
    }
}

숨기기 지연은 상태 표시 줄 scrollToTop 동작에 비해 약간 짧지 만 여전히 멋지게 보입니다.

뷰 컨트롤러에서이 태그가 필요하기 때문에 "isScrollingToTop"상태를 알리기 위해 뷰 태그를 남용하고 있습니다. 다른 것에 태그를 사용하는 경우이를 iVar 또는 속성으로 대체 할 수 있습니다.


테스트하지는 않았지만 대신 DISPATCH_TIME_NOW를 사용하면 다음 실행 루프에서이를 던져야합니다. 이 작업을 수행해 주셔서 감사합니다. 아직 필요하지는 않지만 잘 알고 있습니다.
Dan Rosenstark

얼마 전이고 정확히 기억하지 못하지만 이것이 효과가 없다고 생각합니다. 다음 runloop로 연기하는 것이 일반적으로 그러한 경우에 가장 먼저 시도하는 것입니다.
Ortwin Gentz

2

이전 버전뿐만 아니라 iOS 11과 완전히 호환되어야하는 대답이 있다고 생각합니다 (세로 스크롤).

이것은 새로운 조정 된 ContentInset 을 고려 하고 또한 navigationBar에서 prefersLargeTitles 가 활성화되어 있을 때 필요한 추가 오프셋을 고려합니다.이 은 기본값이 무엇이든 위에 추가 52px 오프셋이 필요한 것으로 보입니다.

조정 된 ContentInset이 titleBar 상태 (큰 제목 대 작은 제목)에 따라 변경되기 때문에 약간 까다 로웠으므로 titleBar 높이가 무엇인지 확인하고 이미 큰 상태 인 경우 52px 오프셋을 적용하지 않아야했습니다. navigationBar의 상태를 확인하는 다른 방법을 찾을 수 없으므로 높이가 44.0 이상인지 확인하는 것보다 더 나은 옵션이 있으면 듣고 싶습니다.

func scrollToTop(_ scrollView: UIScrollView, animated: Bool = true) {
    if #available(iOS 11.0, *) {
        let expandedBar = (navigationController?.navigationBar.frame.height ?? 64.0 > 44.0)
        let largeTitles = (navigationController?.navigationBar.prefersLargeTitles) ?? false
        let offset: CGFloat = (largeTitles && !expandedBar) ? 52: 0
        scrollView.setContentOffset(CGPoint(x: 0, y: -(scrollView.adjustedContentInset.top + offset)), animated: animated)
    } else {
        scrollView.setContentOffset(CGPoint(x: 0, y: -scrollView.contentInset.top), animated: animated)
    }
}

Jakub의 솔루션에서 영감을 받음


2

탐색 막대 가 scrollView 내용의 작은 부분 과 겹치면 내용이 맨 위에서 시작하지 않는 것처럼 보이는 경우가 매우 흔 합니다 . 그것을 고치기 위해 나는 두 가지 일을했다.

  • 크기 검사기-스크롤보기- 컨텐츠 삽입-> 자동에서 사용 안함으로 변경하십시오.
  • 크기 경위 - Constraints- "에 상단 정렬"(상위 정렬 제약) - 두 번째 항목 -> 변경 Superview.Top에서 안전 Area.Top에0 값 (상수 필드) 세트

컨텐츠 삽입-절대 ScrolView.Top을 안전 영역에 맞 춥니 다.


1

스크롤을 위해 맨 UITableViewController, UICollectionViewController또는 UIViewController필요UIScrollView

extension UIViewController {

  func scrollToTop(animated: Bool) {
    if let tv = self as? UITableViewController {
        tv.tableView.setContentOffset(CGPoint.zero, animated: animated)
    } else if let cv = self as? UICollectionViewController{
        cv.collectionView?.setContentOffset(CGPoint.zero, animated: animated)
    } else {
        for v in view.subviews {
            if let sv = v as? UIScrollView {
                sv.setContentOffset(CGPoint.zero, animated: animated)
            }
        }
    }
  }
}

0

SWIFT 5에서 콘텐츠 오프셋을 0으로 설정하십시오.

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

-4

나는 모든 방법을 시도했다. 그러나 아무것도 나를 위해 일하지 않았다. 마침내 나는 이것을 좋아했다.

self.view .addSubview(self.scroll)viewDidLoad에 코드 줄을 추가했습니다 . 스크롤보기를위한 프레임 설정을 시작한 후 스크롤보기에 구성 요소를 추가했습니다.

그것은 나를 위해 일했다.

self.view .addSubview(self.scroll)처음 에 줄 을 추가했는지 확인하십시오 . UI 요소를 추가 할 수 있습니다.


이것을 삭제하십시오. 당시에는 분명히 의미가 있지만 하위 뷰 계층 문제는이 질문과 관련이 없습니다.
Dan Rosenstark

1
스크롤보기가보기 계층 구조에 없거나 컴퓨터가 꺼져 있으면 @Cristik은 물론 작동하지 않습니다. 그러나 영업 이익 요청 뭔가 꽤 좁은
댄 Rosenstark는
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.