Interface Builder에서 UIScrollView를 어떻게 사용합니까?


95

UIScrollView과거에는 프로그래밍 방식으로 조작하여 성공적으로 사용했지만 Interface Builder에서 독점적으로 설정하여 작동시키는 데 어려움이 있습니다.

내 iPhone 앱에 간단한 "정보"페이지가 있습니다. 그것은이 UITextView내 다른 애플 리케이션에 일부 아이콘 및 링크를. 이 모든 뷰를 내에 추가 UIScrollView하여 전체 크기가 480 이상이되도록 정렬했습니다. 내 앱을 시작하면 스크롤 뷰 는 화면에 맞는 콘텐츠 만 표시하고 스크롤은 없습니다.

IB를 통해이 작업을 완전히 수행 할 수 있습니까? 아니면 코드를 통해 contentSize를 조작해야합니까?

답변:


130

UIScrollView의 contentSize 속성을 설정하는 것을 잊었습니다. 이상하게도 Interface Builder에서 이것을 할 수 없습니다. 이 스크롤 뷰를 관리하는 뷰 컨트롤러에서 수행해야합니다.


42
와, IB가 좀 무의미하게 ...이게 속임수 였어, 고마워.
George Armhold

20
(0,0)에 하위 뷰가 하나만 있는지 확인한 다음 해당 하위 뷰를 기반으로 contentSize를 자동으로 설정하는 UIScrollvView의 하위 클래스를 만들 수 있습니다.
Stefan Arentz

1
그것은 내가 한동안받은 최고의 조언이다. 스크롤 뷰가 작동하지 않는 이유를 알 수 없었고 다른 곳에서는 contentSize에 대한 정보를 찾지 못했습니다. 감사.
Drew C

46
Interface Builder에서 contentSize를 설정하는 방법을 알아 내려고했는데이 토론을 찾았습니다. 적어도 저에게는 Xcode 4.5에서 "User Defined Runtime Attributes"를 사용하여 contentSizetype 이라는 항목을 추가 Size하고 원하는 값을 설정하여 설정할 수 있습니다.
nlogax

5
나는 iOS가 적어도 기본 동작으로 하위 뷰의 크기에 따라 스크롤 뷰를 자동으로 설정contentSize 하지 않는 이유에 대해 여전히 당황 합니다 .
aroth

113

Boby_Wan의 대답으로 생각하고 인터페이스 빌더에서 UIScrollView의 contentSize를 구성하는 다음 솔루션을 찾았습니다.

  1. UIScrollView스토리 보드 장면에서 선택
  2. Identity inspector로 이동하여 새 사용자 정의 런타임 속성을 만듭니다 (+ 버튼 클릭).
  3. 속성 키 경로 를 다음으로 변경하십시오.contentSize
  4. 속성 유형 을 다음으로 변경하십시오.Size
  5. 이제 을 { 원하는 콘텐츠 너비 , 원하는 콘텐츠 높이 }로 설정합니다.

예를 들어 값을 {320, 920}으로 설정하면 사용자가 iPhone에서 전체 추가 화면을 아래로 스크롤 할 수 있습니다.

(xcode 4.3.3을 사용하고 있으며 프로젝트의 iOS 배포 대상 은 5.1입니다.)

처음이 작업을 수행했을 때 다음 오류가 발생했습니다.

잘못된 구성 :
     4.3
     MainStoryboard.storyboard 이전의 Xcode 버전을 사용하는 크기 유형 사용자 정의 런타임 속성

이 오류가 발생하면 간단하게 수정할 수 있습니다. 프로젝트 네비게이터 에서 스토리 보드를 선택 하고 파일 관리자를 불러옵니다 . Interface Builder Document 섹션을 찾아 확장하면 Development에 대한 드롭 다운이 있습니다. 다음으로 설정되어 있는지 확인하십시오.Xcode 4.3


7
굉장한 발견! 추신 : 이것이 Apple이 할 수있는 최선의 방법이라는 것이 놀랍습니다. 나는 이것이 Apple 직원조차도 자신의 도구 (인터페이스 빌더)를 사용하지 않는다는 것을 보여줍니다. :).
Adam

훌륭합니다. 이것은 Xcode 4.4에서 저에게 효과적이었습니다. 그러나 이제 IB에서 "볼 수없는"스크롤 뷰 부분에 버튼을 어떻게 배치합니까?
Robert Atkins

1
방금 해결했습니다. 포인터가 여전히 "화면"안에있을 때 드래그를 놓아야합니다. 그렇지 않으면 시작할 때 다시 스냅됩니다. 얼마나 고통 스러운가.
Robert Atkins

그런 식으로 시도했지만 오류가 발생 "this class is not key value coding-compliant for the key keyPath"합니다. 내가 뭘 잘못하고 있는지 도와 주시겠습니까? 제발 참고 내가 사용하는 것이 자 마린-IOS-C #을
SoftSan

25

자동 레이아웃 (iOS6 +)을 사용하면 contentSize. 대신 다음 제약 조건을 설정하십시오.

  1. 스크롤 뷰의 상단을 최상위 자식 상단에 고정합니다.
  2. 그리고 바닥을 최하위 아이의 바닥에 고정하십시오.

1
감사합니다-설정 contentSize이 Xcode 5 및 iOS 7에서 작동하지 않습니다
colincameron 2014 년

18

Interface Builder 만 사용하여 수행 할 수 있으며, Identity Inspector (세 번째 검사기 탭)로 이동하여 다음을 사용하여 새 사용자 정의 런타임 속성을 추가 할 수 있습니다.

  • 키 경로 : contentSize
  • 유형 : 크기
  • 값 : {너비, 높이}

14

이제 스토리 보드UIScrollView 를 떠나지 않고 스크롤 을 만드는 방법이 있습니다 .

  1. 을 선택하십시오 UIScrollView스토리 보드에서 이동 크기 관리자 와 변경 하단 의 값 (또는 당신이 무엇을 변경해야하는 다른 값) 내용 인 세트 컨텐츠 영역의 높이에 절을 참조하십시오.
  2. 이제 Identity inspector 로 이동하여 새 사용자 정의 런타임 속성 (+ 버튼 클릭)을 만들고 이름을 contentSize. 입력 하는 유형 또는 은 중요하지 않습니다 (기본값을 그대로 둘 수도 있음).

이것은 만들 것입니다 UIScrollView두 번째 단계가 필요한 이유는 모르겠지만, 제대로 일을 (나는 우연히 발견). :(


하단 값을 무엇으로 변경 하시겠습니까?
zakdances

콘텐츠 영역의 높이로 변경합니다. 작동하는 것 같고 사용자 정의 "contentSize"속성에 제공 한 값을 대체합니다.
Reid Ellis

예, Reid, 맞습니다. 하단 값을 콘텐츠 영역의 높이로 변경해야합니다. 이를 반영하기 위해 원래 게시물을 편집했습니다. 감사합니다!
RoberRM 2015 년

4

내가 과거에 사용한 한 가지 접근 방식은 인터페이스 빌더의 뷰를 포함하는 스크롤 뷰를 드래그하여 실제 크기를 contentSize로 설정하는 것입니다.

인터페이스 빌더에 대해 본질적으로 분명하지 않은 것은 펜촉에 저장되어 있지만 펜촉이 주로 사용하는 메인 뷰의 일부가 아닌 관련되지 않은 뷰를 가질 수 있다는 것입니다.

scrollview를 원하는 뷰에 자리 표시 자로 사용하는 간단한 UIView를 배치하십시오. (이것은 단순히 위치를 시각적으로 디자인 할 수 있도록하기위한 것입니다. 전체보기를 사용하는 경우이 단계를 건너 뛰고이 답변의 끝에있는 두 번째 코드 스 니펫을 사용할 수 있습니다).

그런 다음 스크롤 뷰를 컨트롤로 채우고 원하는 방식으로 시각적으로 배치 할 수 있습니다. 뷰 컨트롤러 내부에 자리 표시 자와 scrollview 속성을 모두 제공하여 런타임에 액세스 할 수 있도록합니다.

런타임에-(void) viewDidLoad

scrollView.contentSize = scrollView.frame.size;
scrollView.frame = placeholder.frame;
[placeholder.superview addSubView:scrollView];
[placeholder removeFromSuperview];

또는 (자리 표시자를 사용하지 않은 경우) :

CGRect f = self.view.frame;
scrollView.contentSize = f.size;
f.origin.x = 0;
f.origin.y = 0;
scrollView.frame = f;
[self.view addSubView:scrollView];

마지막으로 인터페이스 빌더에서 스크롤 뷰를 "잃어버린"경우 (디자인 그리드에서 사라지도록 닫을 수 있음) 당황하지 마십시오. 디자인 그리드의 왼쪽에있는 개체 목록에서 클릭하면됩니다.


1
감사합니다. 잘 작동했습니다. 또한 자리 표시 자 및 스크롤 뷰에 대해 YourViewController.h에서 IBOutlets를 선언하고 인터페이스 빌더에서 연결해야합니다. 그리고 마지막으로, dot.notation은 xCode에서 세 번째 줄에 대해 평가하지 않았으므로 정상적인 메시지 전송 구문을 사용했습니다. 그러면 모든 것이 훌륭하게 작동했습니다!
jiy

걱정 마. 어떤 사람들은 "정확한"코드가 모든 상황에서 작동 할 것이라고 기대하는 것보다 개념을 이해하는 데 사용할 수없는 코드 조각을 게시 할 때 항상 위험합니다.
동기화되지

이것이 제가 실제로 사용하는 방법입니다. 이 프로그램의 크기를 조정할 필요조차 없습니다. 나는 그것이 의도 된 방식이라고 생각합니다. 하나의 정답입니다.
user4951

밖에서 그린 후 슈퍼 뷰로 이동하겠습니다. 타다.
user4951

실제로 스크래치 패드를 위해 장면 외부의 일부 뷰 디자인을 사용하기 시작했으며, 이와 관련이없는 상황에서도 삶을 훨씬 더 쉽게 만듭니다. 이 답변에 감사드립니다.
Benjamin

4

Autolayout을 사용하는 Xcode 4.5에서는 크기 검사기에 Content Insets 섹션이 없습니다. 그래서 User Defined Runtime Attributes 아래에 추가해야했는데 제대로 작동했습니다.

"사용자 정의 런타임 속성"에 추가하는 것은 "Rect"유형 (Rect와 동일한 입력을 갖는 UIEdgeInsets)이고 {top, left}, {bottom, right}로 정의되는 keyPath == contentInset입니다. contentSize는 scrollview 창의 영역 만 정의합니다. contentInset은 스크롤 가능 영역을 정의합니다.

나는 이것이 같은 상황에있는 누군가에게 도움이되기를 바랍니다.


UITextView 사용은 "textContainerInset"키 패스
디마 Deplov

4

위의 많은 답변은 오해의 소지가 있거나 구식입니다. 2017 년 (아마도 훨씬 이전)부터 인터페이스 빌더 자동으로 크기가 조정 된 콘텐츠로 스크롤 뷰를 지원합니다. 트릭은 XCode가 스크롤 뷰와 그 안에있는 콘텐츠 사이의 제약 조건에 특별한 비표준 의미를 제공한다는 것입니다. 이러한 "내부"제약 조건은 예상대로 콘텐츠의 크기에 실제로 영향을주지 않습니다 .

이것은 예를 들어 여백이없는 메인 뷰의 하단에 스크롤 뷰를 고정 할 수 있고 여백이없는 스크롤 뷰의 하단에 스크롤 뷰의 콘텐츠를 고정 할 수 있지만 실제로 콘텐츠가 늘어나지는 않습니다. 대신 콘텐츠는 자체 결정된 크기 (아래에 더 있음)를 갖게되며 스크롤 뷰 내 스크롤 가능 영역의 크기도됩니다.

다음과 같이 생각하십시오. 제약 조건을 스크롤 뷰에 바인딩하는 데 비대칭이 있습니다. 스크롤 뷰에서 "외부"(부모) 세계로의 제약 조건은 평소와 같이 스크롤 뷰의 크기와 위치를 결정합니다. 그러나 스크롤 뷰 "내부"제약은 실제로 스크롤 뷰를 콘텐츠에 바인딩하여 스크롤 뷰의 스크롤 가능 영역의 크기와 위치를 설정합니다.

제약 조건을 설정하려고 할 때 XCode는 항상 현재 간격을 제안하고 충돌하는 방식으로 내부 및 외부 직면 제약 조건을 의도적으로 변경하지 않을 수 있기 때문에 이것은 완전히 분명하지 않습니다. 그러나 위에서 설명한 의미를 가질 수 있습니다. 하나는 스크롤 뷰 레이아웃을 제어하고 다른 하나는 스크롤 가능한 콘텐츠 영역 크기를 제어합니다.

나는 우연히 이것을 우연히 발견하고 그것이 어떻게 작동하는지 보았습니다.이 기사를 완전히 설명하고 이에 대한 Apple 문서 소스를 인용합니다.

https://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

콘텐츠의 자체 결정 크기에 대한 마지막 중요한 정보 : 일반적으로 콘텐츠의 크기를 부모보기의 너비와 같기 때문에 여기서 catch-22에 있다고 느낄 수 있지만이 경우 부모는 스크롤보기이고 위에서 설명한대로-제약 조건은 콘텐츠 크기에 영향을주지 않습니다. 여기에 대한 답은 항목을 뷰 계층 구조에서 직접 인접하지 않은 항목으로 제한 할 수 있다는 점을 기억하는 것입니다. 예를 들어 스크롤 뷰를 사용하기 위해 헛된 시도를하는 대신 콘텐츠 뷰의 너비를 기본 뷰의 너비로 설정할 수 있습니다. 당신을 위해.


2

Interface Builder에서 View Controller의 Properties 아이콘을 클릭하면 Simulated Metrics에서 "Freeform"크기로 설정하고 기본 View의 크기를 원하는 콘텐츠 크기로 변경할 수 있습니다.

이렇게하면 ScrollView의 콘텐츠를 하나의 큰보기처럼 만들 수 있습니다. 시뮬레이션 된 메트릭 일 뿐이므로 뷰 컨트롤러는로드 될 때 창의 경계에 맞게 크기가 조정됩니다.


2

Interface Builder를 통해 UIScrollView를 설정하는 것은 직관적이지 않습니다. 설정을위한 체크리스트는 다음과 같습니다.

  1. UIViewController의 XIB 파일을 선택하십시오. 인터페이스 빌더의 "Identity Inspector"에서 UIView를 클래스 유형 UIScrollView로 변경하십시오.

  2. "파일 검사기"에서 자동 레이아웃을 선택 취소합니다.

  3. "Attributes Inspector"에서 크기를 Freeform으로 변경합니다. 그런 다음 스크롤 뷰를 수동으로 늘리거나 "크기 검사기"에서 사용자 정의 너비와 높이를 지정할 수 있습니다.

  4. "Identity Inspector"에서 "Size"유형의 "contentSize"라는 새로운 사용자 정의 런타임 속성을 추가하고 {320, 1000}과 같은 값으로 변경합니다. 더 이상 프로그래밍 방식으로 설정할 수 없으므로 Scroll View가 Scroll View의 내용이 창보다 크다는 것을 인식하도록이 단계가 필요합니다.


2

scrollview에서 autoLayout을 제거하십시오. 코드는 다음과 같이 간단합니다.

scrollviewName.contentSize = CGSizeMake(0, 650);

.h 파일에 iboulet 속성을 만든 다음 .m 파일에 합성하면됩니다. 스크롤이 활성화되어 있는지 확인하십시오.


1

예, st3fan 이 맞습니다. UIScrollView의 contentSize 속성을 설정해야합니다. 그러나 이러한 목적으로 자동 레이아웃을 끄면 안됩니다. 코드없이 IB에서만 자동 레이아웃으로 UIScrollView의 contentSize를 쉽게 설정할 수 있습니다.

UIScrollView의 autolayout contentSize를 사용하는 경우 직접 설정되지 않은 경우 UIScrollView의 모든 하위보기에 대한 제약 조건에 따라 계산된다는 점을 이해하는 것이 중요합니다. 그리고 필요한 것은 양방향의 하위보기에 대한 적절한 제약 조건을 제공하는 것입니다.

예를 들어 하위 뷰가 하나만있는 경우 상단 및 하단에서 슈퍼 뷰 (예 : scrollView)까지 높이와 공간을 설정할 수 있습니다. contentSize.height는 합계로 계산됩니다.

Vertical Space (aSubview.top to Superview.top) + aSubview.height + Vertical Space (aSubview.top to Superview.top)

contentSize.width는 수평 제약 조건에서 유사하게 계산됩니다.

contentSize를 제대로 계산할 제약이 너무 적 으면 View Controller Scene 항목 근처에 작은 빨간색 버튼이 표시되어 레이아웃 모호성을 알려줍니다.

하위보기가 많으면 Danyal Aytekin 답변 에서와 같이 상단에서 상단으로의 하위보기, 하위보기 사이의 높이 및 공간과 하단에서 하단으로의 공간 등 제약의 "체인"일 수 있습니다 .

그러나 실제로 대부분의 경우 필요한 크기의 빈 뷰를 추가하고 scrollView의 상단, 왼쪽, 하단, 오른쪽에 공백을 0으로 설정하는 것이 더 편리합니다. 합니다.이보기를 "콘텐츠보기"로 사용할 수 있습니다. 즉, 다른 모든 하위보기를 배치합니다. 이미 많은 하위보기가 있고이를 이동하고 레이아웃을 다시 설정하지 않으려는 경우이 보조보기를 기존 하위보기에 추가하고 숨길 수 있습니다.

scrollView를 스크롤 가능하게하려면 계산 된 contentSize가 scrollView 크기보다 커야합니다.


1

Autolayouts를 사용하여 StoryBoard에서 UIScrollView를 가질 수 있습니다. 기본적으로 필요한 것은 다음과 같습니다.

  1. UIScrollView 추가
  2. 여기에 모든 제약 조건을 추가합니다 (예 : 위쪽, 왼쪽, 오른쪽, 아래쪽 가장자리의 삽입)
  3. UIScrollView에 '컨테이너'UIView 추가
  4. 한 방향 스크롤 (예 : 세로) 만 원하는 경우 : 높이를 명시 적으로 설정 (예 : 600)하고 너비를 UIScrollView의 너비에 연결합니다.
  5. 양방향 스크롤을 원한다면 너비와 높이를 모두 설정하십시오.

스토리 보드 설정



0

나는 더 편리한 방법을 알아 낸다.

1 : 모든 UI를 포함하도록 스크롤 뷰의 크기를 조정합니다.

2 : 스크롤 뷰의 iboutlet을 추가합니다.

3 : viewDidLoad에서 스크롤 뷰의 frame.size를 저장합니다.
(예 : _scrollSize = _scrollView.frame.size;)

4 : viewWillAppear에서 이전에 저장 한 CGSize로 contentSize를 설정합니다.
(예 : _scrollView.contentSize = _scrollSize;)

5 : 완료 ~


0
  1. UIViewController 추가
  2. UIViewController 'Attribute Inspector-> Simulated Metrics'에서 크기 설정 자유 형식
  3. UIViewController 'Size Inspector-> View Controller'에서 높이 800을 설정합니다.
  4. UIViewController에 UIScrollView 추가
  5. UIScrollView (위, 왼쪽, 오른쪽, 아래)에 모든 제약 조건을 추가하고 정렬 추가 X = 가운데
  6. UIScrollView에 UIView 추가
  7. UIView (위, 왼쪽, 오른쪽, 아래)에 모든 제약 조건을 추가하고 X = 가운데 정렬을 추가합니다. 예, # 3의 UIScrollView와 동일하지만 UIView의 경우
  8. UIView에 높이 제약을 추가합니다. 예 : 780
  9. 운영

스토리 보드


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.