UIScrollView에서 세로 스크롤 비활성화


답변:


121

contentSize의 높이를 scrollView의 높이로 설정하십시오. 그런 다음 수직으로 스크롤 할 것이 없기 때문에 수직 스크롤을 비활성화해야합니다.

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,scrollView.frame.size.height);

이 이상한 문제를 디버깅하는 데 많은 시간을 절약했습니다. 감사!
— jpm

2
@fabb 프레임이 언제 변경되는지 어떻게 알 수 있습니까?
— Sam

137

iOS7 이후 :

첫째 : 콘텐츠 크기 너비는 스크롤 뷰의 너비와 같아야합니다.

두 번째 : initWithNibName :

self.automaticallyAdjustsScrollViewInsets = NO;

그게 다야.


멋진 솔루션입니다. 매력처럼 작동했습니다. 내 ViewController의 나머지 뷰 크기에 영향을 줍니까? (버튼, 라벨 ..) 나는 "자기"내 경우에 UIViewController에있다, 의미
— voghDev

@voghDev 아니 그것은 스크롤 뷰의 하위 뷰에 영향을 미치지 않습니다.
— Mirko Brunner 2014

Amazing는 문제가있는 뷰 컨트롤러의 viewdidload 메서드에 이것을 추가했습니다.
— StackRunner

navigationController를 사용하고 있고 scrollview가 viewDidLoad 메서드에서 사용하는 것처럼 navigationBar의 제목 뒤에 있습니다. 해결됩니다.
— EFE

1
코드 줄없이 스토리 보드 설정에서 직접 동일한 결과를 얻을 수 있습니다. 스크롤 뷰 컨트롤러를 선택하고 속성 인스펙터에서 "Adjust Scroll View Insets"를 선택 취소하면됩니다.
— Morpheus78

49

예, pt2ph8의 대답이 맞습니다.

하지만 이상한 이유로 contentSize가 UIScrollView보다 높아야하는 경우 UIScrollView 프로토콜 메서드를 구현하는 세로 스크롤을 비활성화 할 수 있습니다.

 -(void)scrollViewDidScroll:(UIScrollView *)aScrollView;

UIViewController에 이것을 추가하십시오.

float oldY; // here or better in .h interface

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x, oldY)];
    // or if you are sure you wanna it always on top:
    // [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x, 0)];
}

사용자가 UIScrollView를 스크롤 할 때 호출되는 메서드 일 뿐이며 이렇게하면 콘텐츠가 항상 동일한 .y를 갖도록 강제합니다.


6
하느님! float oldY;위의 코드를 참조하는 것처럼 .m 파일에서 oldY 변수를 선언하지 마십시오 . 이는 애플리케이션 별 C 스타일 변수 심볼이며, 변수는 컨트롤러 클래스의 인스턴스 멤버로 선언되어야합니다.
— Itachi 2015

21

다음 방법 포함

-(void)viewDidLayoutSubviews{
    self.automaticallyAdjustsScrollViewInsets = NO;
}

스크롤 뷰의 콘텐츠 크기 너비를 스크롤 뷰의 너비와 동일하게 설정합니다.


1
View Controller를 선택하고 속성을 선택 취소하여
— Storyboard에서도이

1
모든 스크롤 뷰에 대해 설정하기 때문에이 기능이 마음에 들지 않습니다. 다이어그램에서 하나의 스크롤 뷰에만 특정 할 수 있기를 바랍니다. 새 ScrollView 클래스 등을 만들지 않고
— visc

20

원하는 방향으로 비활성화하려면 콘텐츠 크기에 0을 전달해야합니다.

세로 스크롤을 비활성화하려면

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,0);

가로 스크롤을 비활성화하려면

scrollView.contentSize = CGSizeMake(0,scrollView.contentSize.height);

1
이렇게하면 뷰의 contentSize가 설정 한 축에 0이되도록 설정됩니다. ContentSize는 콘텐츠의 크기를 나타내므로 화면 높이를 전달하여 해당 프레임을 넘어서는 수직 스크롤을 비활성화하려고합니다. 올바른 것으로 표시된 솔루션이 정확합니다.
— 시스템

이것은 나를 위해 잘 작동했습니다. 높이를 contentSize의 높이로 설정하면 여전히 세로 스크롤이 발생합니다.
— KoreanXcodeWorker 2016-07-15

1
이것은 나를 위해 작동하지 않았습니다. 또한 self.automaticallyAdjustsScrollViewInsets 시도
— StackRunner

이거 야! Scroll View의 높이를 설정하는 것은 나에게 효과가 없었지만 효과가
— 있었습니다

18

콘텐츠 크기를 업데이트하여 세로 스크롤을 비활성화했지만 스크롤 기능은 그대로 유지되었습니다. 그런 다음 스크롤을 완전히 비활성화하려면 수직 바운스도 비활성화해야한다는 것을 알았습니다.

이 문제를 가진 사람들도있을 것입니다.


당신이 나를 구해주었습니다. 내 contentSize와 프레임은 동일했고 내 인생에서 무엇이 잘못되었는지 알아낼 수 없었습니다. 무리 감사!!
— yuf dec.

2
귀하의 대답은 내가 stackoverflow를 좋아하는 이유입니다! :-) 이런 연기 ... 이건 나를 미치게 만들었다! 당신이 옳습니다. 바운스 효과입니다. 바운스 효과를 원하지만 스크롤 할 필요가 없을 때는 원하지 않으므로 스크롤이 필요한지 여부에 따라 코드에서 해당 효과를 비활성화 / 재 활성화하려고합니다.
— Erik van der Neut 2015 년

2
좋아, 런타임에 UIScrollView에서 바운스를 활성화 / 비활성화하는 것은 매우 쉽습니다. 제 경우에는 스크롤 내용의 높이에만 관심이 있고 이것이 트릭을 수행했습니다. self.scrollView.bounces = (BOOL) (self.scrollView.contentSize.height> self.scrollView.frame.size.height);
— 에릭 반 데르 Neut

12
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x,0)];

}

당신은 확인해야합니다 UIScrollViewDelegate

aScrollView.delegate = self;

4

y를 항상 맨 위에 놓으십시오. UIScrollViewDelegate를 준수해야합니다.

func scrollViewDidScroll(scrollView: UIScrollView) {
        scrollView.contentOffset.y = 0.0
}

이렇게하면 스크롤의 감속 / 가속 효과가 유지됩니다.


4

iOS 11에서 안전 영역이 아닌 화면 경계에 고정되는 스크롤 뷰를 만드는 데 관심이 있다면 다음을 추가하는 것을 잊지 마십시오. :

if (@available(iOS 11.0, *)) {
    [self.scrollView setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}

1
아무튼. 천 번 감사합니다! 당신은 내 일 저장
— ha100

0

에서 iOS11 하나는 다음과 같은 속성을 사용할 수 있습니다

let frameLayoutGuide: UILayoutGuide

frameLayoutGuide.topAnchor 및 frameLayoutGuide.bottomAnchor 에 대한 제약 조건을 scrollView 의 일부 하위 뷰 의 동일한 앵커에 설정하면 수직 스크롤이 비활성화되고 scrollView 의 높이는 하위 뷰의 높이와 같습니다.


0

가장 확실한 해결책은 하위 클래스에서 y 좌표 변경을 금지하는 것입니다.

override var contentOffset: CGPoint {
  get {
    return super.contentOffset
  }
  set {
    super.contentOffset = CGPoint(x: newValue.x, y: 0)
  }
}

다음과 같은 상황에서 유일하게 적합한 솔루션입니다.

  1. 허용되지 않거나 대리인을 사용하고 싶지 않습니다.
  2. 콘텐츠 높이가 컨테이너 높이보다 큽니다.

0

많은 답변 contentOffset에는를 0 으로 설정하는 것이 포함됩니다. scrollView 내부의 뷰를 중앙에 배치하려는 경우가있었습니다. 이것은 나를 위해 일했습니다.

public func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = -scrollView.contentInset.top
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.