본문 바로가기

분류 전체보기

(350)
29. List의 부가 기능 구현하기 List의 부가 기능 구현하기 Pull Refresh Apple Developer Documentation developer.apple.com 화면을 아래로 끌어당겨 새로고침 하는 iOS의 가장 보편적인 새로고침 방식이다. struct PullToRefresh: View { @State private var items = AppleProduct.sampleList[0 ..< 2] @State private var index = 2 var body: some View { List(items) { item in Text(item.name) } .animation(.easeInOut, value: items) .refreshable { await refresh() } } private func refresh(..
28. ForEach & Grid ForEach Apple Developer Documentation developer.apple.com struct View_ForEach: View { var items = AppleProduct.sampleList var body: some View { VStack { ForEach(items, id: \.name) { item in Text(item.name) } } } } 중간중간 등장했던 ForEach는 List나 이후에 살펴볼 Grid에서 폭넓게 사용된다. List와 마찬가지로 데이터를 나열한다는 점에서든 동일하지만, Table에 표시하지 않고 데이터들을 '나열' 하기만 한다. ForEach를 표시하는 형식은 ForEach가 어느 View에 Embed 됐는지가 기준이 됨을 기억하자. List의..
27. List #2 List #2 Selection Apple Developer Documentation developer.apple.com 일반 모드 struct SingleSelection: View { var items = AppleProduct.sampleList @State private var selected: AppleProduct? = nil var body: some View { VStack { Text("Selected item: \(selected?.name ?? "_")") List(items) { item in Button { selected = item } label: { Text(item.name) } } } } } 일반적인 List에 Selection 기능을 구현한 경우이다. 특별한 생성자의 사..
26. List #1 List #1 List는 여러 데이터를 각각의 열로써 수직으로 배치하는 View다. 애플의 모든 플랫폼을 지원하며, 각각에 알맞게 표시한다. SwiftUI의 List는 UIKit의 TableView와 같은 기능을 한다. StaticList struct StaticList: View { var body: some View { List { HStack { Text("Hello, World!") Text("Hello, World!") } Text("Hello, World!") Image(systemName: "star") Toggle(isOn: .constant(true)) { Text("On") } } } } List에 Embed 된 View를 각각의 개별 Cell로 구성한다. DynamicList stru..
00. 시작하며 백엔드 Firebase Firebase Firebase는 고품질 앱을 빠르게 개발하고 비즈니스를 성장시키는 데 도움이 되는 Google의 모바일 플랫폼입니다. firebase.google.com DB를 혼자 구성할 능력도, 생각도 없기 때문에 이 부분은 클라우드 서비스를 적극적으로 사용한다. 이번에도 가장 익숙한 Firebase를 활용하는 방향으로 계획했다. 앱 UI Apple Developer Documentation developer.apple.com 역시나 SwiftUI를 사용한다. 22년 iOS16 및 여러 새 OS들의 배포와 함께 SwiftUI 4.0도 함께 출시됐다. 여러 API들이 새로 생겼고, 기존의 API 중 일부가 deprecated 되는 등 변화가 있다. 아직 관련 자료들이 최신화되지..
25. StateObject @StateObject Apple Developer Documentation developer.apple.com struct StateObject_Tutorials: View { @State private var color: Color = Color.gray var body: some View { VStack { NumberView() .frame(width: 200, height: 200) .background(color) .clipShape(Circle()) Button { color = Color(white: Double.random(in: 0.5 ... 1.0), opacity: 1.0) } label: { Text("Change Color") } .padding() } } } 코드는 'Chang..
24. Observable Object & Environment Object Observable Object Apple Developer Documentation developer.apple.com ObservableObject는 ObservableObject, ObservedObject, Published 셋으로 이루어져 동작한다. Observable Object Class 프로토콜로 View에서 인스턴스의 변화를 감시 가능하다. 값이 바뀌면 View의 업데이트가 가능해진다. 주로 View 모델, 공유 데이터를 구성한다. Observed Object Property Wrapper이다. ObservableObject를 감시한다. Published Property Wrapper이다. ObservableObject에서 사용한다. 다른 View에서 해당 속성을 감시할 수 있다. cla..
23. State & Binding UIKit SwiftUI UIKit과 SwiftUI의 가장 큰 차이점은 View(UI)를 직접 업데이트하지 않는다는 점이다. SwiftUI에서 View는 상태(State)에 자동으로 반응한다. 이러한 상태를 나타내는 변수를 Property Wrapper 라고 부르며 자주 사용되는 것들은 다음과 같다. State Binding Environment ObservedObject EnvironmentObject StateObject All SwiftUI property wrappers explained and compared - a free SwiftUI by Example tutorial Was this page useful? Let us know! 1 2 3 4 5 www.hackingwithswift.co..
22. NavigationView & TabView NavigationView Apple Developer Documentation developer.apple.com 정리하는 시점에는 이미 사용이 중단돼 NavigationStack으로 대체됐다. NavigationStack Apple Developer Documentation developer.apple.com 대부분의 modifier는 그대로 사용할 수 있으니 글은 NavigationView를 기준으로 정리하고, 변경된 부분에 대한 설명이 필요할 경우 추가 언급하도록 한다. 앱을 사용하다 보면 아래에서 올라오는 게 아닌, 옆으로 넘어가는 전환 효과와 함께 새로운 화면을 표시하는 경우가 있다. 새로운 화면을 표시하는 과정(왼쪽)을 'Push'라고 부르고, 이전의 화면으로 돌아가는 과정(오른쪽)을 'Po..
04. 동작 검증, 더 나아가기 동작 macOS 문제없이 파일을 저장하고, 최근 사용한 파일의 목록을 불러올 수 있으며, 편집도 제대로 동작한다. iOS iOS도 마찬가지로 잘 동작한다. 더 나아가기 iOS와 macOS에서 모두 잘 동작하지만, 미관상 거슬리는 부분이 하나 있다. 바로 이 부분이다. 심지어 오른쪽 뒤로가기 버튼은 아무런 동작도 하지 않기까지 하는데, 이는 DocumentGroup과 TextEditor의 기본 UI가 겹쳐서 발생하는 문제다. struct ToyEditorApp: App { var body: some Scene { DocumentGroup(newDocument: TextFile()) { file in ContentView(document: file.$document) .toolbarRole(.automati..