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.topAnchorframeLayoutGuide.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.