개발/Swift
긴 text 내용이 minHeight에 잘리는 문제 (onAppear, task)
덤벨로퍼
2025. 4. 18. 17:10
의도한 동작은 최소 160의 높이를 가지고 내용이 길수록 TextEditor도 늘어나야 함
TextEditor(text: $store.content.sending(\\.setContent))
.focused($focusedField, equals: .content)
.frame(minHeight: 160)
.font(.system(size: 16))
.padding(.top, 16)
내용을 처음부터 입력 할떄는 정상 동작하지만
처음부터 content 가 길 경우 160 높이 에서 잘림, 입력하면 동적으로 늘어남
OnAppear 이후에 컨텐츠 갱신
init에서 content 를 세팅해주지 않고
onAppear에서 Store 에 액션 을 보내고 State 변경으로 content 를 갱신하는 방식으로 수정
//View
.onAppear {
store.send(.onAppear)
}
//Reducer
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .onAppear:
switch state.contentType {
case let .post(detail):
state.content = detail.content ?? ""
case let .comment(comment, _):
state.content = comment.content
}
...
일부 해결되었으나 매우 긴 컨텐츠의 경우 여전히 문제가 발생함
옵션 수정하여 초기값이 긴 경우에도 대응 → 여전히 발생
.frame(minHeight: 160, maxHeight: .infinity)
.fixedSize(horizontal: false, vertical: true)
onAppear가 아닌 tast 에서 수행 → 해결
.task {
store.send(.onAppear)
}
뷰 렌더링과 데이터 의 싱크 문제로 추측이 되어 Task.sleep으로 해결 하려했는데 성공함
그런데 시간을 줄이다보니 0.1초도 되길래 sleep빼보니까
여전히 성공함…
onAppear는 안되고 task 는 왜 되는지 AI에게 물어봄
onAppear의 실행 타이밍
.onAppear {
store.send(.onAppear) // 뷰가 메모리에 로드될 때 즉시 실행
}
- TextEditor의 레이아웃이 완전히 준비되기 전에 실행될 수 있음
- 동기적(synchronous)으로 실행
task의 실행 타이밍
.task {
store.send(.onAppear) // 비동기적으로 실행, 다음 런루프까지 대기
}
- SwiftUI의 뷰 렌더링 사이클이 한 번 완료된 후 실행
- MainActor의 다음 런루프까지 대기하므로, TextEditor가 완전히 레이아웃된 후 실행됨