본문 바로가기
공부/[iOS&Swift]

[iOS] UIScrollView에 대하여

by 인생은아름다워 2022. 2. 11.

✏️ UIScrollView

스크롤 및 확대/축소 기능을 허용하는 뷰

→ 대부분의 애플리케이션은 화면에 가로 또는 세로 방향으로의 스크롤이 존재한다. 그래서 ScrollView에 대해 조사해보고자 한다.

 

UIScrollView는 몇몇 UIKit class의 슈퍼클래스이다, 예를 들어서 UITableViw, UITextView 등. 이 말은 테이블뷰와 텍스트뷰 또한 스크롤과 확대/축소 기능이 가능하다는 것이겠지?

 

공식문서를 보다 보니 UIScrollView는 스크롤 및 확대/축소 기능이 있다고 정의된 것처럼 두 가지 측면에 대해 설명하고 있다.

먼저 스크롤 관점에서 보면, 사용자의 터치 신호가 스크롤을 위해서인지 또는 콘텐츠 내의 어떤 뷰를 추적(Track) 하기 위함인지 알아야 할 필요가 있다. 그래서 사용자의 터치 이벤트(정확히는 Touch-down)가 발생할 경우 타이머를 동작시켜서 이 이벤트를 가로채는데(intercept), 타이머 작동(Fire) 이전에 터치하는 손가락이 이동하는지 그렇지 않은지를 통해서 이벤트를 판단한다. 실제로 우리가 ScrollView를 사용하는 아무 앱을 켜서 스크롤을 해 볼 때랑, 어느 한 지점을 일정 시간 이상 터치하고 있을 경우 리액션이 다르다는 것을 알 수 있다. 관련 메서드로는 touchesSouldBegin(_:with:in:), isPagineEnabled, touchesShouldCancel(in:) 등이 있다고 한다.

두 번째는 확대/축소 또는 드래그(Panning) 기능이다. 이러한 gesture를 감지하면 ScrollViw는 콘텐츠의 오프셋과 스케일을 조정한다고 한다. 제스처가 끝나면 필요에 따라서 뷰를 조정한다. 자세한 건 직접 어떤 앱을 켜봐서 확대/축소, 드래그 기능을 사용해보면 될 것 같다.

마지막으로 스크롤 뷰는 delegate을 가질 수 있으며, delegate은 UIScrollViewDelegate프로토콜을 채택해야 한다.


✏️ ScrollView 사용해보기

어떤 뷰를 사용할 때는 항상 다음의 순서로 진행하면 된다.

  1. 레이아웃 잡기 (width, height, x, y)
  2. 뷰의 특성에 맞게 사용하기

먼저 레이아웃을 잡아보자. ScrollView를 만들면 아래 그림처럼 그 내부에 Content Layout Guide와 Frame Layout Guide라는 두 레이아웃이 존재하는 것을 알 수 있다.

여기서 Content layout이란 콘텐츠가 들어가는 공간을 말한다. 즉, 화면보다 더 클 수도 있는 영역이다. 그리고 Frame layout이란 이 ScrollView가 놓이는 영역을 말한다. 이 두 영역을 적절히 Autolayout을 통해 잡아주면 우리가 가로 또는 세로 스크롤을 할 수 있게 되는 것이다.

다시, Storyboard에서 스크롤 뷰를 ViewController의 View에 일치시키도록 Constraints를 줘봤다.

 

그럼에도 저 빨간 줄들과, 다음과 같은 에러가 발생했는데, 알고 보니 여기서 잡아준 것이 바로 Frame layout이고, 실제로 콘텐츠가 배치될 Content layout을 잡지 않았기 때문에 아래 사진과 같은 에러가 나타나고 있었다.

배치될 Content의 height, width가 모두 애매하다는 이야기~!

왜냐면, 지금 스크롤 뷰의 Frame layout을 채워줬지만(viewController의 View에 맞게) 실제로 그 안의 콘텐츠는 어떻게 배치될지 정하지 않은 상황이기 때문이다. UIScrollView의 경우 그 안에 내부적으로 컨텐츠 뷰를 만들어주고 그 콘텐츠 뷰를 적절히 배치해줘야 위의 오류들을 없앨 수 있다.

UIView를 하나 생성하고 이름을 Content View로 변경했다. 이제 이 Content View의 레이아웃을 잡아주면 된다. 여기서 정리를 잘해야 한다 다시 한번 확인해보자.

 

🧐 Content View는 어떤 레이아웃 가이드에 들어가야 할까?

→ 당연히 Content layout guide이다. 자 그러면 Top, Bottom, Leading, Trailing 앵커를 각각 Content layout guide에 맞춰준다.

→ 그러면 width, height는?

여기서 선택이 필요하다. 내가 세로 방향 스크롤을 할지, 가로방향 스크롤을 할 지에 따라서 둘 중 하나를 Scroll View자체에 일치시켜 주고, 나머지 하나는 적당히 잡아준 후에 우선순위를 낮춰줌으로써 동적으로 변할 수 있게 한다!

→ 지금 여기서는 세로 스크롤을 할 예정이니 width를 스크롤 뷰와 일치시키고, height를 적당히 두고 우선순위를 한 200 정도로 낮춰주었다!

Constraints 들은 빨간 불 없이 잘 들어갔고, 우선 시뮬레이터에서 실행도 잘 된다. 그러면 여기에 뭔가를 넣어서 스크롤을 만들어보자!

우선 코드를 사용하지 않고 스토리보드상에서 StackView를 만들고 그 안에 뷰들을 직접 넣는 방법만 간단히 정리하고, 나중에는 StackView에 코드를 넣는 방식이 보기에 좋아 보인다..!

위와 같이 VerticalStackView를 Content View안에 넣어주고 height을 제외하고 다른 곳엔 모두 constraint를 잡아줬다. 이렇게 하여 스택 뷰의 height는 동적으로 관리할 수 있다. 그리고 네 개의 색이 다른 뷰를 만들어줬으며, 적당히 스택 뷰안에 ScrollView의 Frame layout guide의 영역을 침범하도록 constraints들을 잡아줬다. 여기서 다른 기기에서도 이렇게 꽉 차제 동작시키고 싶다면 아무래도 각 view의 width를 상의 뷰와 일치시켜주면 더 좋았을 것 같다. 아무튼 이렇게 만들어주니 아래 영상과 같이 스크롤은 잘 동작한다.

→ 스크롤이 발생하려면 Content layout의 크기 > Frame layout의 크기 조건을 만들어주면 된다.

 

 

🍎 결론

당장 떠올려봐도 내가 알고 있는 거의 대부분의 애플리케이션이 스크롤 뷰를 사용한다. 브라우져, 메신저 모두 스크롤뷰 기반으로 레이아웃이 잡혀있기 때문에 스크롤 뷰의 기본적인 내용은 꼭 숙지하고 있어야겠다.

중요한 것은 아무래도 레이아웃을 잡아주는 것인데, 상황에 따라서(가로 스크롤, 세로 스크롤) 적절하게 응용해가며 레이아웃을 잡는 연습을 많이 해야겠다.

🍎 참고 문서

UIScrollView

Working with Scroll Views

댓글