개발/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가 완전히 레이아웃된 후 실행됨