관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 탭에서 선택한 영역으로 자동 스크롤 구현 방법 (UIScrollView, scrollRectToVisible, 포커싱) 본문

UI 컴포넌트 (swift)

[iOS - swift] 탭에서 선택한 영역으로 자동 스크롤 구현 방법 (UIScrollView, scrollRectToVisible, 포커싱)

jake-kim 2023. 2. 3. 23:08

* 구현에 앞서, 수평 스크롤 뷰 준비 (UIScrollView와 UIStackView 이용)

구현 방법 및 코드는 이전 포스팅 글 참고

UIScrollView와 UIStackView로 구현한 UI

scrollRectToVisible 이해하기

  • rect 영역이 보이게끔 스크롤하는 것
open func scrollRectToVisible(_ rect: CGRect, animated: Bool)
  • 파라미터인 rect는 스크롤 뷰 영역에 포함되어 있지 않으면 동작 x
  • rect 영역이 이미 보이고 있다면 동작 x

https://developer.apple.com/documentation/uikit/uiscrollview/1619439-scrollrecttovisible

  • 만약 화면의 반인, 6부터 보이도록 스크롤하게 하는 방법?

  • scrollRectToVisible에 사용될 rect 구하기
    • 스크롤 되었을때 시작점은 CGPoint로 생각
    • 스크롤의 시작점으로부터 얼마만큼 스크롤 될 것인지는 CGSize
// 사각형의 영역을 그릴려면 필요한 것 point, size
let point = CGPoint(x: view.frame.width / 2, y: view.frame.origin.y)
let size = view.frame.size
let rect = CGRect(origin: point, size: size)

// rect 영역이 보이게끔 스크롤하는 것
myView.scrollView.scrollRectToVisible(rect, animated: true)

6부터 보이도록 스크롤

  • 8이 중심으로 스크롤 되게끔 하려면?

8이 중심이 되도록 스크롤

  • 가운데 위치시킬 button을 획득
let button = myView.buttons[7]
  • 아래처럼 scrollRectToVisible을 사용해야하므로, CGRect를 구하기
scrollView.scrollRectToVisible(rect, animated: true)
  • CGRect 중 size값은 현재 보여지는 프레임 전체 크기가 보여야하므로 scrollView.frame.size 사용
let size = scrollView.frame.size
  • CGRect 중 point값은 평행이동을 사용

1) 평행이동 - 버튼을 스크롤뷰 frame 오른쪽으로 보내기

button.frame.origin.x

----------------------------
|                          |button
----------------------------

2) 평행이동 - 버튼을 scrollView 크기의 반절에 button 크기 반절을 더하면 가운데로 갈 것이므로 계산

(scrollView.frame.width - button.frame.size.width) / 2

3) 1번에서 2번을 빼면 평행이동 완료

button.frame.origin.x - (scrollView.frame.width - button.frame.size.width) / 2
 ----------------------------
 |          button          |
 ----------------------------

(scroll 부분 전체 코드)

let point = CGPoint(
    x: button.frame.origin.x - (scrollView.frame.width - button.frame.size.width) / 2,
    y: button.frame.origin.y - (scrollView.frame.height - button.frame.size.height) / 2
)
let size = scrollView.frame.size
let rect = CGRect(origin: point, size: size)
print(button.frame.origin.x, button.frame.origin.x - (scrollView.frame.width - button.frame.size.width) / 2)

scrollView.scrollRectToVisible(rect, animated: true)

extension으로 만들기

  • 파라미터는 스크롤 될 rect 값과 animated
extension UIScrollView {
    func scroll(rect: CGRect, animated: Bool) {
        let origin = CGPoint(
            x: rect.origin.x - (frame.width - rect.size.width) / 2,
            y: rect.origin.y - (frame.height - rect.size.height) / 2
        )
        let rect = CGRect(origin: origin, size: frame.size)
        
        scrollRectToVisible(rect, animated: animated)
    }
}

* 전체 코드: https://github.com/JK0369/ExScrolling

 

* 참고

https://developer.apple.com/documentation/uikit/uiscrollview/1619439-scrollrecttovisible

Comments