Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 스위프트
- Human interface guide
- swift documentation
- ribs
- HIG
- UICollectionView
- ios
- 클린 코드
- combine
- tableView
- 리펙토링
- RxCocoa
- 리펙터링
- 리팩토링
- swiftUI
- Observable
- Clean Code
- clean architecture
- Protocol
- uitableview
- 애니메이션
- UITextView
- Refactoring
- collectionview
- MVVM
- SWIFT
- map
- rxswift
- Xcode
- uiscrollview
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] setContentOffset completion 구현 방법 (contentOffsetAnimationDuration, 스크롤 속도) 본문
iOS 응용 (swift)
[iOS - swift] setContentOffset completion 구현 방법 (contentOffsetAnimationDuration, 스크롤 속도)
jake-kim 2023. 10. 30. 01:53setContentOffset 개념
- UIScrollView의 메서드이며, CGPoint 좌표를 통해 원하는 곳으로 스크롤 하게끔하는 기능
- 애플에서는 이 메서드에 completion handler를 따로 작성하지 않아 직접 구현이 필요
- completion 구현하는 방법에는 UIView.animate와 CATransaction 등등의 방법이 널리 알려져 있지만 이 방법으로는 completion 동작 x
setContentOffset에 completion 구현 방법
- "contentOffsetAnimationDuration"를 사용하여 UIScrollView의 인스턴스에 setValue로 입력하면 스크롤 속도를 지정할 수 있는 아이디어를 사용
scrollView.setValue(0.5, forKeyPath: "contentOffsetAnimationDuration")
- 또 value(forKey:) 메소드를 사용하면 현재 지정된 스크롤 속도를 가져올 수 있는 점을 이용
let duration = scrollView.value(forKey: "contentOffsetAnimationDuration")
- UIScrollView에 아래처럼 extension으로 구현하며, DispatchQueue.main.asyncAfter와 위에서 얻어온 duration값을 이용하여 completion 처리가 가능
extension UIScrollView {
func setContentOffset(offset: CGPoint, animated: Bool, completion: (() -> ())? = nil) {
let keypath = "contentOffsetAnimationDuration"
guard let duration = value(forKey: keypath) as? Double else { return }
setContentOffset(offset, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
completion?()
}
}
}
ex) 버튼을 눌렀을 때 맨 아래로 이동한 후, 스크롤이 완료된 후 completion 에서 print하는 예제
- UIScrollView 확장
extension UIScrollView {
func scrollToBottom(animated: Bool, completion: (() -> ())? = nil) {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height)
setContentOffset(offset: bottomOffset, animated: animated, completion: completion)
}
func setContentOffset(offset: CGPoint, animated: Bool, completion: (() -> ())? = nil) {
let keypath = "contentOffsetAnimationDuration"
guard let duration = value(forKey: keypath) as? Double else { return }
setContentOffset(offset, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
completion?()
}
}
}
사용하는 쪽)
button.addAction(
UIAction { [weak self] _ in
self?.tableView.scrollToBottom(animated: true, completion: {
print("finish!")
})
}, for: .touchUpInside
)
(완료)
* 전체 코드: https://github.com/JK0369/ExSetContentOffsetCompletion.git
* 참고
https://stackoverflow.com/questions/4404745/change-the-speed-of-setcontentoffsetanimated
https://developer.apple.com/documentation/uikit/uiscrollview/1619400-setcontentoffset
'iOS 응용 (swift)' 카테고리의 다른 글
Comments