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 | 31 |
Tags
- swift documentation
- ribs
- SWIFT
- 리펙터링
- clean architecture
- UICollectionView
- HIG
- collectionview
- UITextView
- 스위프트
- 리펙토링
- Refactoring
- swiftUI
- 리팩토링
- Protocol
- ios
- 클린 코드
- Clean Code
- 애니메이션
- Human interface guide
- map
- uiscrollview
- rxswift
- tableView
- combine
- Xcode
- Observable
- MVVM
- RxCocoa
- uitableview
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - SwiftUI] 키보드와 스크롤 뷰 (키보드 올라올 때 TextField와의 최소 거리만큼 스크롤 방법, safeAreaPadding) 본문
iOS 응용 (SwiftUI)
[iOS - SwiftUI] 키보드와 스크롤 뷰 (키보드 올라올 때 TextField와의 최소 거리만큼 스크롤 방법, safeAreaPadding)
jake-kim 2025. 1. 23. 01:35키보드와 스크롤 뷰
- 스크롤 뷰 안에 있는 TextField를 탭하여 키보드가 등장할 때, 키보드와 TextField 사이의 거리 최소 32만큼 스크롤링 되는 방법?
ex) 키보드와 포커싱된 TextField 사이의 거리를 최소 32로 설정한 예제
구현 아이디어
- 키보드 높이가 변하는 이벤트를 감지
- 키보드가 등장하면 safeAreaPadding을 32로 설정, 키보드가 다시 들어가면 0으로 설정
구현
- 키보드 이벤트 감지
- 키보드 이벤트를 감지하는 ObservableObject 성격의 클래스 구현
public class KeyboardInfo: ObservableObject {
public static var shared = KeyboardInfo()
@Published public var height: CGFloat = 0
private init() {
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardChanged), name: UIApplication.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardChanged), name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardChanged), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
@objc func keyboardChanged(notification: Notification) {
if notification.name == UIApplication.keyboardWillHideNotification {
self.height = 0
} else {
self.height = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0
}
}
}
- 공통화하여 사용하기 쉽게 ViewModifier로 구현
- 키보드가 등장하면 safeAreaPadding을 주입받은 키보드와 텍스트필드 사이의 최소 거리로 설정, 키보드가 다시 들어가면 0으로 설정
struct KeyboardAware: ViewModifier {
var minDisntance: CGFloat
@ObservedObject private var keyboard = KeyboardInfo.shared
func body(content: Content) -> some View {
content
.safeAreaPadding(.bottom, keyboard.height > 0 ? minDisntance : 0)
}
}
- ScrollView에다 해당 modifier를 붙여서 사용
struct ContentView: View {
@State var text = "example"
var body: some View {
ScrollView {
VStack(alignment: .leading) {
...
}
}
.scrollToMinDistance(minDisntance: 32) // <-
}
}
전체 코드)
struct ContentView: View {
@State var text = "example"
var body: some View {
ScrollView {
VStack(alignment: .leading) {
ForEach(0 ..< 20) { i in
Text("Text \(i):")
TextField("Text", text: self.$text)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.bottom, 10)
}
}
.padding()
}
.ignoresSafeArea(.keyboard, edges: .bottom)
.simultaneousGesture(
DragGesture()
.onChanged { _ in
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
})
.scrollToMinDistance(minDisntance: 32)
}
}
public class KeyboardInfo: ObservableObject {
public static var shared = KeyboardInfo()
@Published public var height: CGFloat = 0
private init() {
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardChanged), name: UIApplication.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardChanged), name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardChanged), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
@objc func keyboardChanged(notification: Notification) {
if notification.name == UIApplication.keyboardWillHideNotification {
self.height = 0
} else {
self.height = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0
}
}
}
struct KeyboardAware: ViewModifier {
var minDisntance: CGFloat
@ObservedObject private var keyboard = KeyboardInfo.shared
func body(content: Content) -> some View {
content
.safeAreaPadding(.bottom, keyboard.height > 0 ? minDisntance : 0)
}
}
extension View {
public func scrollToMinDistance(minDisntance: CGFloat) -> some View {
ModifiedContent(content: self, modifier: KeyboardAware(minDisntance: minDisntance))
}
}
* 참고
'iOS 응용 (SwiftUI)' 카테고리의 다른 글
Comments