Form control
입력 필드에 Label과 Message를 붙여 무엇을 입력해야 하는지 안내하는 컴포넌트입니다. Text field, Text area, Select와 같은 입력 필드를 감싸서 사용하며, 접근성 연결을 처리합니다.
입력 컨트롤에 제목(Label)과 도움말(Message)을 붙여 주고, 라벨 ↔ 입력 ↔ 메시지의 접근성 연결을 자동으로 처리하는 래퍼(wrapper) 컴포넌트입니다.
FormControl은 단독으로 값을 입력받지 않습니다. 내부 슬롯(input)에 실제 입력 컴포넌트를 조합해 사용하며, 라벨·필수 표시(*)·도움말/에러 메시지·액세서리(글자 수 카운트 등)를 일관된 레이아웃으로 감싸 줍니다.
FormControl의 .size(_:)·.status(_:)는 슬롯 안의 Montage 입력 컴포넌트(TextField·TextArea· Select)에 자동으로 전파됩니다. 입력 쪽에서 값을 명시하면 그 값이 우선하므로, 보통은 FormControl에 한 번만 설정하면 됩니다.
Note
Montage 입력 컴포넌트는 label(_:required:) 등 같은 이름의 모디파이어를 직접 제공합니다. 단일 입력을 감쌀 때는 FormControl을 명시하지 않고 입력에 바로 붙이는 쪽이 간결하지만, 위 예제처럼 FormControl로 직접 감싸는 구성도 그대로 지원됩니다. 앱에서 만든 커스텀 입력을 감쌀 때나 입력 종류가 런타임에 바뀌어 래퍼 설정을 한곳에 모아 두고 싶을 때는 FormControl을 직접 쓰세요.
struct Context
입력 슬롯 클로저에 전달되는 FormControl의 현재 상태 컨텍스트입니다.
-
Overview
슬롯 입력 컴포넌트가 FormControl의 FormControl.Size·FormControl.Status를 그대로 반영하도록 현재 값을 묶어 전달합니다. 향후 항목이 추가돼도 클로저 시그니처는 바뀌지 않습니다.
let size: Size
현재 FormControl 크기.
let status: Status
현재 FormControl 상태.
init<Input>(input: () -> Input)
입력 컴포넌트를 슬롯으로 받아 FormControl을 생성합니다.
-
Parameters
-
Discussion
FormControl의 size(_:)·status(_:)는 슬롯 안의 Montage 입력 컴포넌트에 자동으로 전파되므로 호출부에서 다시 넘길 필요가 없습니다.
init<Input>(input: (Context) -> Input)
현재 FormControl.Context를 전달받는 슬롯으로 FormControl을 생성합니다.
-
Parameters
-
Discussion
크기·상태 전파는 Montage 입력 컴포넌트에만 자동 적용됩니다. 앱에서 만든 커스텀 입력이 FormControl의 크기·상태를 반영해야 할 때 이 초기화를 사용하세요.
var body: some View
뷰의 내용과 동작을 정의합니다.
func accessory<Accessory>(() -> Accessory) -> FormControl
Footer 우측(trailing)에 표시할 액세서리 뷰를 설정합니다.
-
Parameters
-
Return Value
수정된 FormControl 컴포넌트
-
Discussion
글자 수 카운트, 타이머 등 입력 아래에 붙는 보조 요소를 자유롭게 구성할 수 있습니다. 스타일(타이포그래피·색)은 호출부에서 지정합니다.
func label(String?, required: Bool) -> FormControl
라벨 텍스트와 필수 표시 여부를 설정합니다.
-
Parameters
-
Return Value
수정된 FormControl 컴포넌트
func labelPlacement(LabelPlacement) -> FormControl
라벨 위치를 설정합니다.
-
Parameters
-
Return Value
수정된 FormControl 컴포넌트
func labelWidth(CGFloat) -> FormControl
leading 배치에서 이 컨트롤의 라벨 폭을 명시적으로 고정합니다.
-
Parameters
-
Return Value
수정된 FormControl 컴포넌트
-
Discussion
주 용도는 두 가지입니다. (1) 단독 leading FormControl에서 라벨 폭을 스펙값으로 맞출 때, 그리고 (2) FormControlGroup 안에서 특정 행 하나만 다른 폭으로 둘 때(per-control 값이 컨테이너 폭보다 우선).
컬럼 전체를 고정 폭으로 맞추려면 각 컨트롤에 반복하지 말고 FormControlGroup의
labelWidth를 쓰세요. FormControl.LabelPlacement.top 배치에는 영향이 없습니다.
func message(String?) -> FormControl
도움말/에러 메시지를 설정합니다.
-
Parameters
-
Return Value
수정된 FormControl 컴포넌트
-
Discussion
Note
메시지 색은 status(_:)에 따라 결정됩니다.
.negative에서만 강조 색으로 표시됩니다.
func size(Size) -> FormControl
크기를 설정합니다.
-
Parameters
-
Return Value
수정된 FormControl 컴포넌트
func status(Status) -> FormControl
상태를 설정합니다.
-
Parameters
-
Return Value
수정된 FormControl 컴포넌트
enum LabelPlacement
라벨의 위치입니다.
case leading
라벨을 입력의 leading 쪽에 가로로 배치하고, 입력 슬롯의 첫 줄 중앙에 맞춥니다. (단일 행 입력은 입력 세로 중앙과 같고, 다중 행 입력은 입력 전체가 아니라 첫 줄을 기준으로 정렬됩니다.)
case top
라벨을 입력 위에 세로로 배치합니다. (기본)
enum Size
FormControl의 크기입니다. 라벨 타이포그래피를 결정합니다.
case large
큰 크기 (라벨 label1)
case medium
중간 크기 (라벨 label2)
enum Status
FormControl의 상태입니다. 메시지의 색을 결정합니다.
case negative
에러 상태. 메시지는 강조 색(foregroundNegativePrimary)으로 표시됩니다.
case normal
기본 상태. 메시지는 도움말 색(foregroundNeutralTertiary)으로 표시됩니다.
case positive
성공 상태. 메시지는 기본 도움말과 동일한 색(foregroundNeutralTertiary)으로 표시됩니다.
Conforms To
Swift.Sendable
SwiftUICore.View
라벨이 붙은 입력을 세로로 쌓을 때 라벨 열 폭을 통일해 입력의 시작 위치를 정렬하는 컨테이너입니다.
Leading 배치(FormControl.LabelPlacement.leading)의 라벨들을 대상으로, 내부 라벨의 본연 폭 중 가장 긴 값으로 라벨 열이 맞춰집니다.
개별 행에 폭을 지정할 필요 없이 이 컨테이너로 감싸기만 하면, 내부 leading 라벨들의 본연 폭 중 최댓값으로 라벨 열이 맞춰집니다. Dynamic Type·다국어로 라벨 길이가 바뀌어도 자동으로 재정렬되므로 호출부에 고정 폭(매직 넘버)을 두지 않아도 됩니다.
앱에서 만든 커스텀 입력은 FormControl로 직접 감싸 같은 그룹에 섞어 넣을 수 있습니다.
자동 측정 대신 라벨 열 폭을 고정하고 싶으면 labelWidth를 지정합니다. 이 경우 측정을 건너뛰고 모든 행이 그 폭을 씁니다. (여러 화면에서 동일한 폭을 맞추거나, 측정으로 인한 1프레임 흔들림을 피하고 싶을 때)
Note
FormControl.LabelPlacement.top 배치에는 영향을 주지 않습니다. 특정 행 하나만 다른 폭으로 두려면 그 행에 labelWidth(_:)(또는 입력 컴포넌트의 같은 이름 모디파이어)를 사용하세요. per-control 값이 컨테이너 폭보다 우선합니다.
init(labelWidth: CGFloat?, spacing: CGFloat, content: () -> Content)
컨테이너를 생성합니다.
-
Parameters
var body: some View
뷰의 내용과 동작을 정의합니다.
Conforms To
Swift.Sendable
SwiftUICore.View
