Starbucks Caramel Frappuccino
본문 바로가기
  • 그래 그렇게 조금씩
SwiftUI/SwiftUI(Basic)

34. [SwiftUI] TextEditor, Safe Area에 대한 탐구

by Toughie 2023. 4. 30.

이전 시간에 봤던 텍스트 필드는 '한 줄'에 적합했다.

이제 여러 줄의 입력이 필요한 경우 TextEditor 를 활용해야 한다.

다만 TextEditor는 TextField에 비해 커스텀 하기가 굉장히 어렵다. (제한적이다.)

ex. background modifier를 통해 컬러를 변경할 수 없다. (화이트 디폴트다.)

다만 colorMultiply를 통해 완벽하게는 아니지만 변경할 수는 있다 ㅎㅎ..

그래서 커스텀이 많이 필요한 경우, 여러줄의 인풋이 그다지 필요 없는 경우는 TextField를 활용하자.

 

//  Created by Toughie on 2023/04/30.
//

import SwiftUI

struct TextEditorPrac: View {
    
    @State var textEditorText: String = "hi"
    @State var savedText: String = ""
    
    var body: some View {
        NavigationView {
            VStack {
            //텍스트에디터
                TextEditor(text: $textEditorText)
                    .frame(height: 250)
                    .foregroundColor(Color.black)
                //TextEditor는 배경색 변경 불가
//                    .background(Color.red)
                //colorMultiply로 변경은 가능
                    .colorMultiply(Color.gray.opacity(0.5))
                    .cornerRadius(10)
                    
                Button {
                    savedText = textEditorText
                } label: {
                    Text("Save".uppercased())
                        .font(.headline)
                        .foregroundColor(.white)
                        .padding()
                        .frame(maxWidth: .infinity)
                        .background(Color.blue)
                        .cornerRadius(10)
                    
                }
                Text(savedText)
                    .font(.title)
                
                Spacer()
            }
            .navigationTitle("Text Editor")
            .padding()
            
            // ⭐️ 이 부분에 대해 아래에서 좀 살펴보자
//            .background(Color.yellow.opacity(0.5))
            .background(Rectangle().fill(Color.yellow.opacity(0.5)))
        }
    }
}

텍스트 에디터는 텍스트 필드와 사실 거의 유사하다.

다만 여기서 정리하고 싶은 부분은 배경색을 변경하다가 발견한 문제? 그리고 해결하며 얻은 지식이다.

 

주석 처리된 부분은 원래 작성했던 코드인데, VStack 영역만 노란색으로 바꿔주기 위한 의도였다. (왼쪽 사진처럼)

하지만 VStack 영역에만 노란색이 적용되는 것이 아니라, safeArea 영역까지 색이 변경되는 것이다... (오른쪽 사진)

대체 왜??? 그 이유를 탐구하다가 이유를 알아냈다.

바로 NavigationView의 특성 때문이었다. 사실 safe area 경계선에 대한 개념을 제대로 몰라서 였다고도 볼 수 있겠다.

(현재 예시코드는 네비게이션 뷰 안에 VStack으로 텍스트에디터와 버튼을 감싸둔 형태이다.)

 

먼저 NavigationView은 화면의 상단과 하단의 Safe Area를 기반으로 하여 경계선이 정해진다.

(아래 사진 푸른 선이 safe area)

그래서 NavigationView 안에 VStack 같은 다른 뷰들은 Safe Area를 고려하지 않고 NavigationView 안의 영역에서 그려진다.

-> 내부 view들은 safe area 내부에 위치하기는 하지만 safe area의 크기까지 고려하지 않는다는 말.

 

이 때 VStack과 같은 NavigationView 안의 뷰의 경계선이 Safe Area의 경계선과 겹칠 가능성이 있는 것이다.

-> 겹치니까 겹치는 부분까지 영향을 끼치는 것(ex. 배경색이 같이 변하는 것)

 

(지금 위 사진에서는 safe area 경계선, navigaitonView 경계선, VStack 경계선 전부 겹치는 상황이다.)

 

+ NavigationView의 배경색을 변경하려면 NavigationView 자체에 배경색을 설정해야 하는데,

이때 설정된 배경색은 safe area까지 적용된다. 

-> 이 또한 Safe Area의 경계선과 NavigationView의 경계선이 겹치기 때문에!

 

요약하자면

어 나 safe area까지 배경색 바꿀 의도는 아니었는데? safe area까지 색이 바껴버렸네? 하는 경우는

어떤 뷰의 경계선이 safe area의 경계선과 겹쳐서였던 것이다. 

 

따라서 위의 예시에서는 rectangle을 이용해 이런 이슈를 해결한 것!

 

어우 생각보다 복잡하지만 이해가 안갔었는데 이유를 발견해서 속이 좀 후련하다..ㅋㅋㅋ

무슨 프리뷰 버그인가 했는데 내가 몰랐던 거였어 ㅎ

경계선에 겹치면 겹치는 애들 전부 적용시켜 버렸던 거였다니..