Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- swiftUI
- rxswift
- UITextView
- 리펙터링
- 리팩토링
- uiscrollview
- collectionview
- combine
- Human interface guide
- clean architecture
- HIG
- ribs
- map
- swift documentation
- 리펙토링
- SWIFT
- uitableview
- Protocol
- Refactoring
- 스위프트
- UICollectionView
- 클린 코드
- 애니메이션
- MVVM
- Xcode
- tableView
- Clean Code
- ios
- Observable
- RxCocoa
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - SwiftUI] SwiftUI Sample - Navigation App (About Me, TabView) 살펴보기 본문
iOS 튜토리얼 (SwiftUI)
[iOS - SwiftUI] SwiftUI Sample - Navigation App (About Me, TabView) 살펴보기
jake-kim 2024. 6. 12. 01:41* SwiftUI Sample 앱 살펴보기 전체 목차는 여기 참고
TabView 개념
- SwiftUI에서의 TabView는 선언적으로 매우 직관적으로 사용이 가능
- Text 밑에 TabView를 표현하고 싶은 경우?
- 아래 코드에 TabView 블록을 추가
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
}
}
(TabView 추가)
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
TabView { // <-
}
}
}
- 이제 화면 A, B, C 뷰를 넣고 싶은 경우, 차례로 연달아서 넣기
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
TabView {
ViewA()
ViewB()
ViewC()
}
}
}
- 여기서 Tab의 UI에는 icon과 title로 구성되므로 이 값을 넣어주려면 .tabItem { }을 사용하여 넣어쥐
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
TabView {
ViewA()
.tabItem {
Label("View1", systemImage: "tray.and.arrow.down.fill")
}
ViewB()
.tabItem {
Label("View2", systemImage: "tray.and.arrow.up.fill")
}
ViewC()
.tabItem {
Label("View3", systemImage: "person.crop.circle.fill")
}
}
}
}
- tab에는 우측 상단에 빨간색 알림 UI도 있는데 이것은 그냥 뷰에다가 .badge(2)를 사용하면 가능
- 느낌표와 같은 문자를 입력해도 가능
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
TabView {
ViewA()
.badge(2) // <-
.tabItem {
Label("View1", systemImage: "tray.and.arrow.down.fill")
}
ViewB()
.tabItem {
Label("View2", systemImage: "tray.and.arrow.up.fill")
}
ViewC()
.badge("!") // <-
.tabItem {
Label("View3", systemImage: "person.crop.circle.fill")
}
}
}
}
About Me 프로젝트
- About Me 파일: https://developer.apple.com/tutorials/sample-apps/aboutme
- Project Files를 클릭하여 다운
- 첫 실행부인 @main인 AboutMeApp 구조체 확인
- ContentView가 WindowGroup으로 감싸여진 상태
- WindowGroup 이란?
- Window라는 개념은 뷰들의 컨테이너 역할을 하면서 동시에 터치 이벤트와 같은 이벤트를 가장 먼저 수신하여 subview들에게 이벤트를 전달하는(responder chain) 기능
- macOS와 iPadOS와 같이 그룹으로부터 여러개의 window를 띄울 수 있는 형태일때 WindowGroup을 여러개 정의하여 사용
@main
struct AboutMeApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
- ContentView를 보면 TabView형태인 것을 확인 가능
struct ContentView: View {
var body: some View {
TabView {
HomeView()
.tabItem {
Label("Home", systemImage: "person")
}
StoryView()
.tabItem {
Label("Story", systemImage: "book")
}
FavoritesView()
.tabItem {
Label("Favorites", systemImage: "star")
}
FunFactsView()
.tabItem {
Label("Fun Facts", systemImage: "hand.thumbsup")
}
}
}
}
Text, Image, padding
- 탭 화면 중 HomeView의 UI
- 상단의 Text, 중앙에 Image, 하단의 Text
struct HomeView: View {
var body: some View {
VStack {
Text("All About")
Image(information.image)
Text(information.name)
}
}
}
- 상단의 Text는 폰트가 크고 bold체인 형태이므로 속성 추가
Text("All About")
.font(.largeTitle)
.fontWeight(.bold)
- 하단의 텍스트도 font를 입력해주고 추가
Text(information.name)
.font(.title)
- 중앙의 이미지에도 cornerRadius를 적용하여 추가
Image(information.image)
.cornerRadius(10)
결과)
- 현재 이미지의 contentMode는 scallToFill형태가 되어 공간에 맞게 이미지가 늘어나서 비율이 맞지 않은 상태
- 공간에 맞게 이미지를 resize해야하고, contentMode를 fit으로하여 너비에 이미지 크기를 맞추도록 설정
- 여기서 Image와 위, 아래의 Text, 좌우 패딩을 주고 싶을땐 padding()사용
Image(information.image)
.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(10)
.padding(40) // <-
- padding 인터페이스 확인해보면 edges, length가 있고 length만 입력하면 상하좌우 방향으로 패딩이 적용되는 것
@inlinable public func padding(_ edges: Edge.Set = .all, _ length: CGFloat? = nil) -> some View
@inlinable public func padding(_ length: CGFloat) -> some View
- 아무것도 파라미터로 넘기지 않는 padding()을 사용하면, 아래 설명과 같이 플랫폼에 따라 알맞게 시스템에서 계산해서 padding을 넣어줌
/// You can omit either or both of the parameters. If you omit the `length`,
/// SwiftUI uses a default amount of padding. If you
/// omit the `edges`, SwiftUI applies the padding to all edges. Omit both
/// to add a default padding all the way around a view. SwiftUI chooses a
/// default amount of padding that's appropriate for the platform and
/// the presentation context.
ScrollView
- 두번째 탭 My Story를 보면 스크롤이 있는 UI
- StoryView를 보면 ScrollView로 Text를 단순히 감싼 형태
struct StoryView: View {
var body: some View {
VStack {
Text("My Story")
.font(.largeTitle)
.fontWeight(.bold)
.padding()
ScrollView { // <-
Text(information.story)
.font(.body)
.padding()
}
}
.padding([.top, .bottom], 50)
}
}
ForEach, HStack
- 3번째 탭인 FavoritesView를 보면 수평으로 나열된 UI가 존재
- 이렇게 나열된 형태의 UI는 HStack으로 ForEach를 감싸면 구현이 가능
HStack {
ForEach(information.hobbies, id: \.self) { hobby in
Image(systemName: hobby)
.resizable()
.frame(maxWidth: 80, maxHeight: 60)
}
.padding()
}
.padding()
- 만약 아이템의 개수가 3개가 아닌 4개인 경우는 알아서 줄어드는 UI로 변화
- (4번째 탭은 특별한 UI는 없으므로 스킵)
* 이 밖의 SwiftUI Sample 앱 살펴보기 전체 목차는 여기 참고
* 참고
'iOS 튜토리얼 (SwiftUI)' 카테고리의 다른 글
Comments