SwiftUI에서 스크롤을 맨 아래로 이동하는 방법 입니다.
일반적인 방법
ScrollViewReader를 사용해서 proxy.scrollTo(list.last, anchor: .bottom)로 이동하면 스크롤이 맨 아래로 이동 합니다.
그런데 가장 마지막 row의 높이가 다른 경우 row의 높이를 계산하지 못해서 제대로 이동되지 않습니다.
이 문제는 에뮬레이터에서는 이상 없었는데 아이폰 실제 기기에서 테스트 하니 문제가 발생했습니다.
import SwiftUI
struct TestView: View {
var list: [String] = ["1111", "1111", "1111", "1111", "1111", "1111", "1111"
, "1111", "1111", "1111", "1111", "1111", "1111"
, "1111", "1111", "1111", "1111", "1111", "1111"
, "여러 줄\n1111111\n111111111\n11111111\n111111111111\n1111111111\n1111111111111"]
@State var scrollBottom = false
var body: some View {
VStack {
ScrollViewReader { proxy in
List(list.indices, id: \.self) { index in
let item = list[index]
VStack {
Text(list[index])
}
.listRowSeparator(.hidden)
.id(item)
}
.onChange(of: scrollBottom) { newValue in
if newValue == true {
DispatchQueue.main.async {
proxy.scrollTo(list.last, anchor: .bottom)
}
scrollBottom = false
}
}
}
.onAppear() {
DispatchQueue.main.async {
// 스크롤 맨 아래로 이동
self.scrollBottom = true
}
}
}
}
}
개선 방법
가장 마지막줄에 dummy의 row를 하나 추가하였습니다.
그리고 dummy row의 높이는 0으로 설정 하였습니다.
import SwiftUI
struct TestView: View {
var list: [String] = ["1111", "1111", "1111", "1111", "1111", "1111", "1111"
, "1111", "1111", "1111", "1111", "1111", "1111"
, "1111", "1111", "1111", "1111", "1111", "1111"
, "여러 줄\n1111111\n111111111\n11111111\n111111111111\n1111111111\n1111111111111"]
@State var scrollBottom = false
var body: some View {
VStack {
ScrollViewReader { proxy in
List(list.indices, id: \.self) { index in
let item = list[index]
VStack {
Text(list[index])
}
.listRowSeparator(.hidden)
.id(item)
// 가장 마지막에 Empty 넣어줌
if item == list.last {
VStack {
Text("")
}
.padding(.top, 0)
.padding(.bottom, 0)
.frame(height: 0.0)
.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
.listRowSeparator(.hidden)
.id("BOTTOM_ID")
}
}
.environment(\.defaultMinListRowHeight, 0)
.onChange(of: scrollBottom) { newValue in
if newValue == true {
DispatchQueue.main.async {
proxy.scrollTo("BOTTOM_ID", anchor: .bottom)
}
scrollBottom = false
}
}
}
.onAppear() {
DispatchQueue.main.async {
// 스크롤 맨 아래로 이동
self.scrollBottom = true
}
}
}
}
}
'개발 - iOS SwiftUI' 카테고리의 다른 글
애플 로그인 - 백엔드 스프링 프레임워크 (0) | 2024.06.20 |
---|---|
iOS SwiftUI Button 탭(클릭) 영역 넓히기 (0) | 2023.11.08 |
iOS SwiftUI current View 상태 관리 예제 (0) | 2023.11.05 |
iOS SwiftUI HTTP Multipart POST 예제 (0) | 2023.10.27 |
iOS SwiftUI EnvironmentObject NavigationStack 예제 (0) | 2023.10.25 |