개발을 잘하고 싶은 주니어?

Scroll View 공부하기 - 1 (코드로 추가하기) 본문

개발/iOS

Scroll View 공부하기 - 1 (코드로 추가하기)

데쿠! 2021. 10. 15. 00:25
반응형

스크롤 뷰를 공부해보겠습니다.

스크롤 뷰는 내부 뷰의 스크롤과 줌을 할 수 있습니다. UIView를 상속받습니다.

 

UIScrollView는 UIKit 내부의 클래스들이 상속받고 있습니다. (UITableView, UITextView 등의 클래스)

스크롤 뷰는 손가락의 움직임에 따라서 origin을 그에 따라서 조절합니다. 

스크롤 뷰는 따로 다른 일은 하지 않고 vertical, horizontal scroll indicator로서의 역할만 합니다.

스크롤 뷰는 언제 스크롤을 멈출지를 알아야 해서 content view의 크기를 알아야 합니다 

기본적으로는 끝까지 스크롤을 하면 그 아래로 더 스크롤되지 않고 다시 위로 튕겨 올라갑니다.

 

스크롤 뷰는 보통 많은 텍스트를 처리하고 싶을 때 또는, 큰 이미지를 유저가 줌하고 싶을 때나 더 많은 공간을 보여줄 필요가 있을 때 사용합니다.

 

 

Scroll View와 Auto Layout

스크롤 뷰에 오토 레이아웃을 추가할 때는 고려해야 할 두가지 타입이 있습니다.

1. 스크롤 뷰의 x, y, width, height를 지정하는 것

2. 스크롤 뷰의 content area의 서브뷰의 x, y, width, height를 설정하는 것입니다.

스크롤 뷰와 view hierarchy 외부의 뷰(보통은 super view) 사이에 constraints를 만들 때는 스크롤 뷰의 frame을 설정합니다.

스크롤 뷰와 view hierarchy 내부의 뷰들 사이에 constraints를 만들 때 scrollable content area 내부의 서브 뷰들의 frame을 설정합니다.

스크롤 뷰를 사용할 때는 다음 내용을 꼭! 생각해야 합니다.

  • superview 내부에 위치한 스크롤 뷰의 위치와 크기를 설정하고, 스크롤 뷰의 content area의 크기를 정의해야 합니다.
  • content area를 정의할 때, 스크롤 뷰의 가장자리에 맞추는 것이 제일 좋습니다.
  • 만약 horizontal scrolling(가로로 스크롤)을 원할 때는 content view의 높이와 scroll view의 높이를 같게 합니다.
  • vertical scrolling(세로로 스크롤)을 원할 때는 content view의 넓이와 scroll view의 넓이를 같게 합니다.

 

코드로 scroll view 추가하기

 

우선 scrollView와 내부에 추가할 stackView 상수를 추가해줍니다.

private let scrollView = UIScrollView()
private let mainStackView = UIStackView()
private func setupScrollView(){
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(scrollView)
    
    NSLayoutConstraint.activate([
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
    ])
}

scrollView를 현재 뷰에 추가하고 scroll view의 top, bottom, leading, trailing을 현재 뷰에 맞춰줍니다.

private func setupMainStackView(){
    mainStackView.axis = .vertical
    mainStackView.distribution = .equalSpacing
    mainStackView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(mainStackView)
    // 1
    let contentLayoutGuide = scrollView.contentLayoutGuide
    NSLayoutConstraint.activate([
    	// 2
        mainStackView.widthAnchor.constraint(equalTo: view.widthAnchor),
        mainStackView.topAnchor.constraint(equalTo: contentLayoutGuide.topAnchor),
        mainStackView.leadingAnchor.constraint(equalTo: contentLayoutGuide.leadingAnchor),
        mainStackView.trailingAnchor.constraint(equalTo: contentLayoutGuide.trailingAnchor),
        // 3
        mainStackView.bottomAnchor.constraint(equalTo: contentLayoutGuide.bottomAnchor)
    ])
    
    setupButtons()
}

스크롤 뷰에 addSubview를 가지고 스택 뷰를 추가해줍니다.

스크롤 뷰에 넣을 stack view에 대해서도 각 속성들과 오토 레이아웃을 설정해줍니다.

1. contentLayoutGuide는 스크롤 뷰의 Content Layout Guide의 레퍼런스를 포함합니다.

이 레이아웃 가이드는 스크롤 뷰의 content area를 말합니다. 이 레이아웃 가이드로 constraints를 추가하면 좀 더 명확하게 코드를 구현할 수 있습니다.

2. mainStackView의 width에 대한 제약사항을 추가합니다. widthAnchor는 content area가 아니라 view와 관련해서 설정을 해주는데 그 이유는 스크롤 뷰의 크기는 서브 뷰의 크기에 따라 결정이 되는데 만약 mainStackView의 Width를 view와 똑같이 만들어주지 않으면 스크롤 뷰가 줄어들 위험이 있기 때문입니다.

또한 width를 설정해줌으로서 horizontal scrolling이 disabled 됩니다. 

3. mainStackView와 contentLayoutGuide의 bottom을 동일하게 해 줍니다. 위에서 말했다시피 스크롤 뷰의 크기는 content area에 영향을 받습니다. 따라서 bottom을 맞춰줌으로써 content가 늘어날 때마다 스크롤 뷰의 크기도 늘어나도록 해줍니다.

private func createButtons(text: String, color: UIColor = .blue) -> UIButton{
    let button = UIButton(type: .system)
    button.setTitle(text, for: .normal)
    button.setTitleColor(color, for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.heightAnchor.constraint(equalToConstant: 50).isActive = true
    button.contentHorizontalAlignment = .center
    return button
}

func setupButtons(){
    let buttonTitles = "123456786546456345235236356".map{ word in
        return String(word)
    }
    let buttonStack = UIStackView()
    buttonStack.translatesAutoresizingMaskIntoConstraints = false
    buttonStack.distribution = .equalSpacing
    buttonStack.axis = .vertical
    buttonStack.alignment = .fill
    buttonTitles.forEach { title in
        buttonStack.addArrangedSubview(createButtons(text: title))
    }
    
    mainStackView.addArrangedSubview(buttonStack)
    NSLayoutConstraint.activate([
        buttonStack.widthAnchor.constraint(equalTo: mainStackView.widthAnchor),
        buttonStack.heightAnchor.constraint(equalTo: mainStackView.heightAnchor)
    ])
}

또한 mainStackView에 들어갈 buttonStack을 만들고 원하는 속성으로 설정해줍니다.

mainStackView에 buttonStack을 추가하고 buttonStack의 오토레이아웃을 설정해줍니다.

여기서 주의할 점은 addSubview나 addArrangedSubview를 통해서 추가한 다음에 오토레이아웃을 설정해줘야 한다는 것입니다.

 

Frame Layout Guide로 scroll view 설정하기

private func setupScrollView(){
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(scrollView)
    // 1
    let frameLayoutGuide = scrollView.frameLayoutGuide

    NSLayoutConstraint.activate([
        frameLayoutGuide.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        frameLayoutGuide.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        frameLayoutGuide.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        frameLayoutGuide.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
    ])
}

1. scrollView.frameLayoutGuide에 대한 레퍼런스인 frameLayoutGuide 상수를 생성합니다.

이 레이아웃 가이드는 content area를 의미하는 것이 아니라 scroll view의 frame에 대한 layout guide입니다.

다시 말해서 스크롤 뷰 내부의 content크기와 관계없이 스크린에 보이는 스크롤 뷰의 크기를 의미합니다. (스크롤 뷰 자체의 크기)

 

 

 

[스크롤 뷰 공부 출처 : Raywenderich] https://www.raywenderlich.com/books/auto-layout-by-tutorials

 

Auto Layout by Tutorials

 

This book will be your guide as you explore and master the many capabilities of Auto Layout.

This book is for iOS developers of all skill levels, from those just getting started building user interfaces to the experienced hands who want to get mo

www.raywenderlich.com

 

[스크롤 뷰 공부 출처 : 애플 공식 문서] https://developer.apple.com/documentation/uikit/uiscrollview/ 

반응형
Comments