Programming

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

procodes 2020. 6. 1. 21:02
반응형

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


UIScrollView를 맨 위로 스크롤하려면 어떻게합니까?


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];

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

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

용법:

myScrollView.scrollToTop()

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


스위프트 4

scrollView.setContentOffset(.zero, animated: true)

사용하다 setContentOffset:animated:

[scrollView setContentOffset:CGPointZero animated:YES];

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)

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

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

rob mayoff의 답변 의 스위프트 3.0.1 버전 :

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

상태 표시 줄 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 동작에 비해 약간 짧지 만 여전히 멋지게 보입니다.

Note that I'm abusing the view tag to communicate the "isScrollingToTop" state because I need this across view controllers. If you're using tags for something else you might want to replace this with an iVar or a property.


I think I have an answer that should be fully compatible with iOS 11 as well as prior versions (for vertical scrolling)

This takes into account the new adjustedContentInset and also accounts for the additional offset required when prefersLargeTitles is enabled on the navigationBar which appears to require an extra 52px offset on top of whatever the default is

This was a little tricky because the adjustedContentInset changes depending on the titleBar state (large title vs small title) so I needed to check and see what the titleBar height was and not apply the 52px offset if its already in the large state. Couldn't find any other method to check the state of the navigationBar so if anyone has a better option than seeing if the height is > 44.0 I'd like to hear it

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

Inspired by Jakub's solution


Scroll to top for UITableViewController, UICollectionViewController or any UIViewController having 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)
            }
        }
    }
  }
}

It's very common when your navigation bar overlaps the small portion of the scrollView content and it looks like content starts not from the top. For fixing it I did 2 things:

  • Size Inspector - Scroll View - Content Insets --> Change from Automatic to Never.
  • Size Inspector - Constraints- "Align Top to" (Top Alignment Constraints)- Second item --> Change from Superview.Top to Safe Area.Top and the value(constant field) set to 0

Content insets - Never Align ScrolView.Top to Safe Area.Top


I tried all the ways. But nothing worked for me. Finally I did like this.

I added self.view .addSubview(self.scroll) line of code in the viewDidLoad. After started setting up frame for scroll view and added components to scroll view.

It worked for me.

Make sure you added self.view .addSubview(self.scroll) line in the beginning. then you can add UI elements.

참고URL : https://stackoverflow.com/questions/9450302/get-uiscrollview-to-scroll-to-the-top

반응형