Bibi's DevLog 🤓🍎

UIScrollView 코드로 만들기 본문

📱🍎 iOS

UIScrollView 코드로 만들기

비비 bibi 2022. 4. 22. 23:06

UIScrollView

https://velog.io/@nnnyeong/iOS-UIScrollView-%EB%8B%A4%EB%A3%A8%EA%B8%B0-autolayout-programatically
https://velog.io/@inwoodev/Swift-ScrollView-%EC%BD%94%EB%93%9C%EB%A1%9C%ED%99%94%EB%A9%B4%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

UIScrollView

: A View that allows the scrolling and zooming of its contained views.

UIScrollView - ContentLayout, FrameLayout

UIScrollView의 두 요소

  • ContentLayout : 스크롤 뷰 안에 들어가는 모든 뷰들을 담고 있는 영역에 대한 Layout
    • 예시) 창문 밖의 강아지가 차지하는 공간
  • FrameLayout : 실제로 scroll view에 의해 보여지게 되는 영역에 대한 Layout
    • 예시) 창문의 크기

ScrollView와 ContentView

  • scrollVIew (UIScrollView)
    • contentView에 맞게 origin이 조정됨
    • scrollView의 frame에 들어오는 부분을 clip함
    • 손가락의 움직임을 추적하고, 그에 따라서 origin을 조정한다.
    • scrollView의 Constraint는 화면 safeArea에 맞춘다
      • view.safeAreaLayoutGuide.topAnchor
  • contentView (UIView)
    • (필수) scrollView에 들어갈 구체적인 뷰.
    • scrollView는 내부 내용(contentView)에 의해 스크롤됨 - 하얀 도화지를 깔아주는 개념으로 ScrollView에 ContentView를 깔아 주어야 한다.
    • contentView의 Constraint는 scrollView의 contentLayoutGuide에 맞춘다
      • scrollView.contentLayoutGuide.topAnchor
      • contentView의 크기는 scrollView가 보여지는 영역보다 커질 수 있으므로, frameLayoutGuide가 아닌 contentLayoutGuide에 맞춰야 한다.
  • (vertical scroll) 적용하기 : contentView와 scrollView의 width는 동일하게 맞춘다.

UIScrollViewDelegate

메서드 활용해서 기능 구현하기

UIScrollView는..

직접 상속할 일은 많지는 않다

  • UITableView, UICollectionView, UITextView ... 등 많은 클래스가 이미 UICollectionView를 상속받았기 때문에.

UIScrollView 코드로 구현하기

  1. 뷰컨트롤러에서 scrollview(UIScrollView)와 contentview(UIView 등) 만들기
  2. self.view.addSubview(scrollView)
  3. scrollview.addSubview(contentView)
  4. scrollView의 constraint 지정
  5. contentView의 constraint 지정 - scrollView의 top bottom leading trailing에 맞추어 지정
  6. 스크롤 방향 설정 : 세로 스크롤을 원한다면 contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true.
  7. contentView에 스크롤을 원하는 긴 컨텐츠를 넣어 스크롤이 되는지 확인

아래는 예시 코드입니다.

HomeViewController


import UIKit

class HomeViewController: UIViewController {
    static let identifier = "HomeViewController"

    private let scrollView = UIScrollView()
    private let contentView = HomeVerticalScrollContentView()

    override func viewDidLoad() {
        super.viewDidLoad()
        //self.title = "Home"

        self.scrollView.delegate = self

        setViews()
        setViewConstraints()
    }

    private func setViews() {
        self.view.addSubview(scrollView)
        scrollView.addSubview(contentView)

        scrollView.backgroundColor = .brown
        contentView.backgroundColor = .systemPink
    }

    private func setViewConstraints() {
        configureVerticalScrollViewConstraint()
        configureContentViewConstraint()
    }

    private func configureVerticalScrollViewConstraint() {
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            scrollView.topAnchor.constraint(equalTo: self.view.topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
            scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
        ])
    }

    private func configureContentViewConstraint() {
        contentView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
            contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
        ])
        // vertical scroll view
        contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true

    }
}

extension HomeViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("scrolled")
    }
}

HomeVerticalScrollContentView


import UIKit

class HomeVerticalScrollContentView: UIView {

    private let mockLabel: UILabel = {
        let label = UILabel()
        label.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
        label.numberOfLines = 0
        label.sizeToFit()
        label.backgroundColor = .systemGray3
        return label
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setUI()
        setConstraint()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setUI()
        setConstraint()
    }

    private func setUI() {
        addSubview(mockLabel)
    }

    private func setConstraint() {
        configureMockLabelConstraint()
    }

    private func configureMockLabelConstraint() {
        mockLabel.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            mockLabel.topAnchor.constraint(equalTo: self.topAnchor),
            mockLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            mockLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor),
            mockLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor)
        ])
    }
}