본문 바로가기

swiftUI

(12)
01. 프로젝트 구성, UI 구현 프로젝트 구성 Coredata는 위와 같이 수정한다. 완료 여부를 판단할 isCompleted, 할 일의 정보를 저장할 각각의 속성이다. // 수정 전 import CoreData struct PersistenceController { static let shared = PersistenceController() static var preview: PersistenceController = { let result = PersistenceController(inMemory: true) let viewContext = result.container.viewContext for _ in 0.. Content init(displayPendingTask: Bool, filterDate: Date, content:..
00. 시작하며 시작하며 최근 앱들을 여럿 스토어에 등록했는데 슬슬 사용자들이 직접 데이터를 생성하고, 이를 관리할 수 있는 기능들에 대한 아이디어가 많아지고 있다. WWDC 2023을 기준으로 SwiftUI는 새로운 데이터 관리 도구인 SwiftData를 지원하기 시작했고, 이는 기존의 CoreData를 SwiftUI의 스타일에 맞도록 사용하는 새로운 패러다임이고 익숙해져야만 한다. 이를 위해 당분간은 CoreData를 기반으로 한 프로젝트들을 위주로 공부를 진행하고, SwiftData를 배워보면서 부족했던 부분을 채우고, 한 발 더 나아가는 기회로 삼고자 한다. 앱 Swift Swift - Apple Developer Swift is a powerful and intuitive programming language ..
PHPickerViewController가 특정 이미지를 불러오지 못하는 문제 서비스 중인 JusTheme의 업데이트를 준비하던 도중 작업에 필요한 유틸리티 앱을 만들었다. 스토어 등록을 위해 마무리 준비를 하던 도중 특정 이미지를 불러오지 못하는 문제를 발견해서 이를 수정했다. 결론부터 말하자면 PHPicker는 현재 애플에서 제공하는 가이드라인 대로 작업하면 WebP를 제대로 표시할 수 없다. 애플이 권장하는 PHPicker의 구현 방식은 다음과 같다. Meet the new Photos picker - WWDC20 - Videos - Apple Developer Let people select photos and videos to use in your app without requiring full Photo Library access. Discover how the PHPi..
ParallaxEffect 구조 구조는 단순하다. ScrollView 내에 상단에 이미지를 표시할 여백과 내용을 표시할 VStack 등의 View가 존재한다. 구현 ContentList struct ContentList: View { var body: some View { VStack(alignment: .leading) { ForEach(0.. 0 Spacer() .frame(height: isScrolled ? 400 + offsetY : 400) .background { Image("sample") .resizable() .scaledToFill() .offset(y: isScrolled ? -offsetY : 0) .blur(radius: isScrolled ? offsetY / 20 : 0) } } .frame(heigh..
05. 인터페이스 디자인 #2 인터페이스 디자인 #2 앱 설정, 디자인 다듬기 앱 설정 기기의 모든 상태에 대처할 수 있다면 더할 나위 없이 좋겠지만, 가진이 없다면 예상이 되는 상황은 미리 차단하는 것도 방법이다. 앱 설정 | 화면 방향 고정하기 인터페이스를 디자인할 때 offset 등의 고정값을 사용하지 않았기 때문에 큰 문제는 없지만, 이렇게 화면의 방향이 바뀌면 서로의 영역을 침범하는 문제가 생긴다. 따라서 이 앱에서는 Portrait 모드만 지원하도록 앱의 Deployment Info를 변경한다. 이제부터 이 앱은 iPhone의 Portrait 모드 상태로만 제공된다. 앱 설정 | 화면 모드 고정하기 애플은 iOS13부터 darkmode를 지원하기 시작했다. 기본으로 제공하는 API에는 대비가 돼있어 크게 신경 쓸 부분은 없..
04. 기능구현 #3 기능구현 #3 이미지 저장 이미지 저장 | 저장 기능 이미지를 생성하다 마음에 들면 앨범에 저장해 공유할 수 있도록 기능을 구현한다. .toolbar { ToolbarItem(placement: .navigationBarLeading) { NavigationLink { InfoView() } label: { Image(systemName: "info.circle") } } ToolbarItem(placement: .navigationBarTrailing) { Button { //share } label: { Image(systemName: "square.and.arrow.up") } } } 앞서 생성한 ToolbarItem에 기능을 추가한다. .toolbar { ToolbarItem(placement: ..
SwiftUI에서 Blur를 사용하는 4가지 방법 Blur Apple Developer Documentation developer.apple.com struct ContentView: View { var body: some View { ZStack() { Image("bg.sample") .resizable() .ignoresSafeArea() .scaledToFill() .blur(radius: 20) Text("Blur") .font(.largeTitle) .foregroundColor(.white) } } } iOS13 부터 지원하는 blur는 가장 간단한 방법이지만 Image Layer에 적용해야 한다는 단점이 존재한다. 이는 해당 방식으로는 TextView의 frame에만 blur 효과를 주기 어렵다는 의미이기도 하다. VisualEffect ..
03. 기능구현 #2 기능구현 #2 이미지 표시하기 이미지 표시하기 | ContentView > Button struct ContentView: View { @ObservedObject var viewModel = ViewModel() @State var image: UIImage? @State var text = "" var body: some View { NavigationView { VStack { Spacer() 앞서 초기화 한 ViewModel을 사용하기 위해 ObsevedObject로 viewMocdel 인스턴스를 생성한다. var body: some View { NavigationView { VStack { Spacer() if let image = image { Image(uiImage: image) .resi..
02. 기능 구현 #1 기능 구현 #1 OpenAiKit OpenAIKit | APIKey 생성 간단한 회원가입을 하고, 'View API Keys'를 선택한다. 화면에 표시되는 'Create new secret key' 버튼을 눌러 API Key를 생성하면 되는데, 이후 표시되는 안내창에 적혀있듯 확인창을 닫으면 Key는 더 이상 확인 할 수 있는 방법이 없다. 따라서 닫기 전에 복사 할 수 있도록 하고, 메모장 등에 적어 놓도록 하자. OpenAiKit | Import Swift Package Manager를 사용해 Package를 추가한다. GitHub - MarcoDotIO/OpenAIKit: Swift Package for OpenAI's API Swift Package for OpenAI's API. Contribu..
01. 인터페이스 디자인 #1 인터페이스 디자인 #1 ContentView 간단한 기능을 하는 만큼 간단한 구성을 가진다. NavigationView toolbar ImageView TextView TextField Button ContentView | NavigationView & Toolbar struct ContentView: View { var body: some View { NavigationView { VStack { } .navigationTitle("Image Generator") .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button { //info } label: { Image(systemName: "info.circle") } } ToolbarItem(..