1. CupertinoSliverNavigationBar
https://www.youtube.com/watch?v=xiTuAwvKxBY&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG

특징
- iOS 디자인 가이드라인을 따르는 상단 앱바 제공
- 스크롤을 내리면, Large Title이 자연스럽게 줄어들면서 middle 위치의 작은 타이틀로 전환됨
- → iOS 기본 앱과 동일한 UX
- 안드로이드의 AppBar안 CupertinoNavigationBar와는 달리 스크롤에 반응하는 동적 크기 변화(타이틀의 크기 자동 전환 등)를 지원
주의사항
- 기본적으로 stretch 효과를 지니고 있지 않기 떄문에 과한 확장 애니메이션 등을 기대할 수 없습니다.
- CupertinoSliverNavigationBar는 일반 위젯이 아니라 Sliver이기 때문에 반드시 CustomScrollView 안에서 사용해야 합니다.
활용 예제
| leading | 좌측 아이콘 (뒤로가기, 프로필 등) |
| trailing | 우측 액션 버튼 (추가, 설정 등) |
| middle | 축소된 상태의 타이틀 |
| largeTitle | 확장된 상태의 타이틀 |
CustomScrollView(
slivers: [
CupertinoSliverNavigationBar(
middle: Text("DashBook"),
largeTitle: Text("dashbook"),
leading:Icon(CupertinoIcons.person_2),
trailing: Icon(CupertinoIcons.add),
automaticallyImplyLeading: true, //뒤로가기버튼 자동 여부 pop이 가능하면 자동으로 뒤로가기 아이콘 생성
)
]
)
2. CupertinoRadio
https://www.youtube.com/watch?v=D0xwcz2IqAY&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&index=2

특징
- Material의 Radio와 같은 개념을 지님
- 여러 옵션 중 하나만 선택해야할 때 사용
- ios 환경에 맞는 옵션 선택 구성요소
- 제네릭 타입 <T>를 사용함
주의사항
- 단독 사용시 ux가 좋지 않기 때문에 보통은 ListTile계열과 함께 사용하는 것이 좋습니다.
- groupValue과 T의 타입이 일치해야 합니다. groupValue가 nullable면, <T?>로 맞추는 것이 안전합니다.(타입 불일치로 인한 컴파일 에러 주의)
활용 예제
//일반적으로 enum을 사용하여 타입을 처리함
enum SingingCharacter {
lafayette,
jefferson
}
SingingCharacter? _character = SingingCharacter.lafayette //그룹을 공유(하나만 선택되도록)
//원하는 유형을 넣어 처리(<T> 값임)
CupertinoRadio<SingingCharacter>(
value: SingingCharacter.lafayette, //값 이름
groupValue: _character, //그룹
onChanged: (SingingCharacter? value){...}, //선택 시 실행함수
activeColor: Colors.purple, //활성화 색상
inactiveColor: Colors.purple, //비활성화 색상
fillColor: Colors.purple, //채우기 색상
)
CupertinoRadio<SingingCharacter?(
value: SingingCharacter.jefferson,
groupValue: _character,
onChanged: (SingingCharacter? value){
//상태 변경을 넣어줘용
setState(() {
_character = value;
}
}
)
//만약 레이블을 추가하고싶다면 CupertinoListTile를 상위로 하여 함께 사용하는 것을 추천
3. CupertinoSheetRoute
https://www.youtube.com/watch?v=5H-WvH5O29I&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&index=3

특징
- ios스타일의 모달 뷰
- 화면 하단에서 올라오며, 기존 화면을 완전히 덮지 않음
- push나 직접 호출을 통해 불러올 수 있음
- 기존의 창 위에 새 시트를 쌓거나 시트 내에서 새 페이지로 이동하는 등의 작업을 처리
- CupertinoSheetRoute를 통해 중첩 네비게이션이 가능하여 경로 간 원활한 전환이 가능함
- 사용자가 아래로 스크롤하면 중첩된 경로를 포함한 시트를 닫을 수 있음
- pop나 popSheet로 닫을 수 있음
주의사항
- 딥 링크나 상태 복원과 같은 복잡한 사용 사례의 경우 해당 위젯은 사용하지 않는 것을 권장합니다.
//기본 사용 예제
Navigator.of(context).push(
CupertinoSheetRoute<void>(
builder: (BuildContext context) {
return SomePage();
}
)
);
//showCupertinoSheet(권장)
showCupertinoSheet(
context: context,
userNestedNavigation: true, //중첩된 네비게이터가 있는 CupertinoSheetRoute를 얻을 수 있음
pageBuilder: (BuildContext context) {
return SomePage(
CupertinoButton(
onPressed: ()=>
Navigator.of(context).push(someRoute);
showCupertinoSheet(...)
)
);
}
);
//앱 최상위 네비게이터에 시트를 띄우고 싶을때, 사용
Navigator.of(context, rootNavigator:true).push(CupertinoSheetRoute(...));
Navigator.of(context, rootNavigator:true).pop(); //최상위 네비게이터 기준 POP
CupertinoSheetRoute.popSheet(context); //현재 열린 Sheet만 안전하게 닫음(시트 구조가 복잡할 때 이 방식을 권장)
4. CupertinoSlidingSegmentedControl
https://www.youtube.com/watch?v=esnBf6V4C34&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&index=4

특징
- 여러 옵션에서 값을 선택할 수 있으며, ios환경에 어우러지는 가로형 버튼 목록
- TabBar와 같은 페이지 전환 보다는 상태 전환에 초점을 둠.
- 자식 노드의 정렬된 맵을 통해 분할 제어를 처리
- 값은 Widget로 어떤 위젯이든 가능하고, 키값은 T로 자유롭게 입력
- 선택되지 않은 키값을 입력 시, onChange를 통해 상태 변경 및 작업 처리(함수 update...참고)
- Map에 표시된 순서대로 목록이 표시됨
- 크기는 자식 위젯의 높이에 따라 결정됨
- 너비는 가장 [넓은 자식 요소의 고유 너비 or 사용 가능한 가로 공간을 자식 요소 수로 나눈 값] 중 더 작은 값으로 선택됨
주의사항
- 세그먼트의 수가 많아지면 가독성이 떨어질 수 있으므로, 2~4개 정도를 권장합니다.
- 페이지 전환 용도로 사용할 경우, ios UX와 어긋나므로 지양할 것을 추천합니다
enum Emotion { happy, sad, shocked }
Emotion _selectedEmotion = Emotion.happy;
sementsMap = <T,Widget>{
Emotion.happy : Image(...),
Emotion.sad : Image(...),
Emotion.shocked : Image(...),
}
void updateSelectedEmotion(Emotion? value) {
if(value!=null) {
setState(() {
_selectedEmotion = value;
})l
}
}
CupertinoSlidingSegmentedControl<Emotion>(
children: segmentsMap,
groupValue: _selectedEmotion,
onValueChanged: updateSelectedEmotion,
padding: EdgeInsets.all(10),
thumbColor: pastelBlue, //썸네일색상
backgroundColor: pastePurple,
disabledChildren:{ //특정 세그먼트 비활성화
Emotion.sad,
...,
},
)
5. CupertinoCheckbox
https://www.youtube.com/watch?v=ua54JU7k1Us&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&index=5

특징
- - 체크가 가능한 다중 선택용 체크박스
- 목록에서 여러 옵션을 선택해야 하는 경우에 사용함
주의사항
- ios에서는 체크박스를 너무 많이 사용하게 된다면 체크박스보다는, 스위치형 토글을 사용할 것을 권장하고 있습니다.
- tristate: true인데 value를 null 처리하지 않으면 UX적으로 의미 없는 상태가 될 수 있습니다.
- radio와 마찬가지로, 단독 사용시 ux가 좋지 않기 때문에 보통은 ListTile계열과 함께 사용하는 것이 좋습니다.
bool? _isChecked = true; //true, false, null가능
CupertinoCheckbox(
checkColor: CupertinoColors.activeOrange,
value: _isChecked,
tristate: true, //true로 설정해야함
fillColor: WidgetStateProperty<Color?>fromMap({
WidgetState.selected: Colors.purple,
...
});
activeColor: CupertinoColors.activeBlue, //모든 컬러를 통일하고 싶을 떄, 사용
onChanged: (bool? value){...} //토글 시 수행할 작업
);
6. CupertinoSwitch
https://www.youtube.com/watch?v=24tg_N4sdMQ&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&index=6

특징
- 토글 위젯으로, 탭 뿐 아니라 드래그 제스쳐도 지원
- apple의 사용자 인터페이스 가이드라인에서는 작은 화면이나 사용자의 주의를 특정 컨트롤로 유도하고자 할 때 사용할 것을 권장
- ios에서 가장 표준적인 토글 컨트롤
- 스위치 온오프 여부, 선택 시 실행되는 함수 콜백 총 두가지를 필수 값으로 받음
- 테마가 활성화된 경우, 트랙 색상은 테마의 기본 색상과 일치함
- 테두리를 넣거나 이미지를 삽입하는 등의 커스텀 또한 가능함
주의사항
- 단순 선택(여러개 중 하나)이나 다중 선택 개념에는 부적합합니다.
- 비동기 작업(API호출 등)을 연결할 경우에는 실패 시의 상태 롤백 처리가 별도로 필요합니다.
- 이전 위젯들과 같은 이유로 단독 사용보다는 ListTile계열과 함께 사용하는 것이 권장됩니다.
//아래 두가지처럼 테마가 설정되어있는 경우 해당 테마 색상을 따름
CupertinoApp -> applyThemeToAll: true
or
CupertinoSwitch->applyTheme: true
bool isSelected = false;
CupertinoSwitch(
value: isSelected, //필수
onChanged: (bool? value) { //필수
setState(() {
isSelected = value ?? false;
});
},
activeTrackColor: CupertinoColors.systemPurple, //기본 트랙의 스타일
inactiveTrackColor:CupertinoColors.systemPurple, //기본 트랙의 스타일
thumbColor:CupertinoColors.systemPurple,//엄지손가락 색상
inactiveThumbColor:CupertinoColors.systemPurple,
);
추가적으로 계속해서 내용을 추가할 예정임미다!!!
'개발 > 플러터(Flutter)' 카테고리의 다른 글
| Flutter 위젯 탐방기 - 오늘의 위젯 정리하기[단축키편] (0) | 2026.02.09 |
|---|---|
| Flutter 위젯 탐방기2 - 오늘의 위젯 정리하기 (0) | 2026.01.25 |
| [플러터(Flutter)] - jsonserializable로 API요청 최적화하기 (4) | 2024.10.06 |
| [플러터(Flutter)] -로딩을 지루하지 않게.. Skeleton 적용해보기! (2) | 2024.10.02 |
| [플러터(Flutter)]- Admob으로 내가 만든 앱에 광고 넣어보기(1)_ 기본적인 셋팅을 진행하자 (0) | 2024.03.19 |