본문 바로가기
Xcode/IOS

SwiftUI) SwiftUI 체험기#1 - 다양한 Binding

by 후르륵짭짭 2022. 8. 20.
728x90
반응형

안녕하세요. 후르륵짭짭입니다.

2019년에 SwiftUI가 처음으로 공개 되었는데, 2022년 3년이 지나서 찍먹 중 찍을 한번 해봤습니다. (쫌 많이 늦은 느낌이 들지만 ㅠ ㅠ)

2020년 6월에 IOS 개발을 처음 접했는데, 그 때 감정으로 다시 접하게 됐습니다.

https://developer.apple.com/tutorials/swiftui/creating-and-combining-views

 

Apple Developer Documentation

 

developer.apple.com

< 해당 사이트에서 Landmark라는 프로젝트 이름으로 튜툐리얼을 진행 할 수 있습니다. >

애플의 Tutorial을 보면서 SwiftUI 프로젝트를 진행하고 제가 다시 저만의 스타일로 다시 만들어봤습니다.

 

** 종합적인 느낌 **

일단 굉장히 UIKit과 다른 느낌이였습니다. 

UIKit은 규칙이 정해진 문서에 글을 적어가는 느낌이였는데, SwiftUI는 블록을 쌓는 느낌이 들었습니다.

- 개발 환경 -

일단 Build를 할 필요없이 Preview로 UI를 개발할 수 있기 때문에 개발 속도가 많이 빨라진 느낌이 듭니다.

사내 프로젝트는 Build 시간이 오래 걸려서 단위테스트를 만들어서 검증하는게 더 빠르기도 하니깐요

하지만,,, 노트북이 좋아야 할 것 같습니다.

이렇게 작은 프로젝트 돌리는데도 Intel 맥북 옛날 제품이면 많이 힘들어 합니다.

 - UI -

개인적인 느낌이지만 View를 만드는데 훨씬 적은 시간이 들었습니다.

UIKit을 처음 배울 때, 혼자서 저렇게 만들려면 일주일은 공부해야지 가능했을 겁니다.

그런데 SwiftUI는 더 짧은 시간안에 학습이 가능했습니다.

하지만 아직 배움이 짧아서 부족해서 그렇지만 세세한 View를 그리는데, UIKit 보다 어렵다는 느낌이 들었습니다.

SwiftUI는 자동으로 View의 크기를 만들어주는데,

세세한 것을 배치 줄 때는 AutoLayout이 한번 익히면 더욱 쉽다는 생각이 들었습니다.

 - 기능 - 

일단 UI를 그려주는 것에서 확실히 다릅니다.

UIKit은 View의 생명주기가 있어 해당 생명주기에 맞춰 View를 그려주게 됩니다.

그리고 만약 View를 다시 그려주고 싶다면 layout를 직접 변경하고 변경 되었다고 알려줘야합니다.

반면 SwiftUI는 React 처럼 지정한 값이 변경이 되면 View를 다시 그려주는 형태로 되어 있습니다. ( 그래서 적응하기 쉽지 않았습니다..)

- 설계 -

UIKit은 주로 MVC 아니면 MVVM으로 개발을 해왔습니다.

특히 사내에서는 MVVM을 사용하는데, 그때 View - ViewModel - Usecase - Repository - Service 이렇게 세세하게 분리하고

ViewModel에서 상태값을 관리하고 View를 다시 그려주는 식으로 사용했습니다.

SwiftUI도 비즈니스 로직과 View를 분리하기하는 것을 장려하기 때문에 MVVM 디자인 패턴을 적용해서 작업했습니다.

실제로 View에서는 일반적인 비즈니스 로직을 넣을 수 없기 때문에같은 비즈니스 로직을 담당하는 Object가 필요했습니다.

하지만 계속 개발하면서 SwiftUI에 MVVM이 맞나???? 이런 생각이 들었습니다.

State나 EnviormentObject, 또는 Binding 등 View에서 상태값을 관리하는 기능을 많이 제공하는데 

오직 비즈니스 로직에서만 상태값을 관리하는 방식이 올바른 방식인가??? 라는 생각이 들더군요.

이 부분에 대해서는 좀더 깊게 공부해볼 필요가 있을것 같습니다.

 

** 다양한 Binding **

SwiftUI에서는 다양한 Binding기능을 제공하는데, 지금 간략하게 정리해보겠습니다.

 - State - 

State는 View에서 상태관리를 하는 대표적인 바인딩 입니다.

isCircle값이 변경 될 때 View를 다시 그려주게 됩니다.

 

- Binding -

Binding은 PropertyWrapper의 값을 받아 값을 변경 해주는 바인딩 입니다.

- 초기화 

@Binding private var landMark : Landmark
init(landMark : Binding<Landmark>){
        self._landMark = landMark
}

Binding을 초기화 할때는 self._바인딩이름 을 넣어 줘야합니다.

바인딩을 사용하는 두가지 방법이 있습니다.

- 값을 변경할 필요 없을 때 

LikeView(likeNum: .constant(1))

이렇게 Binding을 그냥 일반 상수로 사용할 때 값을 넘겨줘야 한다면 다음 처럼 넘겨주면 됩니다.

근데 저렇게 사용하려고 Binding을 사용하는 건 아닙니다 절대로 ㅋㅋㅋㅋ

- 값이 변경 된 것을 모두 공유하고 싶을 때

1.
@ObservedObject private var viewModel : LandMarkViewModel
LandmarkDetail(landMark: $viewModel.originData[content.id - 1001])

2.
@State private var isPresented = false
ColorChangeView(state: $isPresented)

이렇게 상위 뷰에서 하위뷰로 ProperyWrapper로 감싸져 있는 값을 Binding에게 전달하면 

값이 변경 되는 동시에 View를 다시 그려줄 수 있게 됩니다.

그때 " $ "을 붙여줘서 보내줘야합니다.

 

- ObservableObject -

ObservableObject는 이 객체는 바인딩 기능을 가진 객체라는 것을 알려줍니다.

ObservableObject는 상태 변화를 알려주는 대표적인 방법 두가지가 있습니다.

- Published 선언

@Published var originData : [Landmark] = []

이렇게 변수에 Published를 선언 해주면 해당 originData가 변경 될 때 마다 상태를 감지하게 되고 

이 ObservableObject를 감시하고 있는 View는 View를 다시 그려주게 됩니다.

 - objectWillChange.send()
 
 func toggleFavorite(){
        filterWithFavorite = !filterWithFavorite
        objectWillChange.send()
 }

아니면 직접 objectWillChange.send()를 호출해주는 방법도 있습니다.

 

이렇게 ObservableObject 구성을 마쳤으면 View에 다음과 같이 

@ObservedObject private var viewModel : LandMarkViewModel

를 선언 해주면 됩니다.

!!! 주의 !!!

 의존성 주입이 아닌 방법으로 @ObservedObject를 선언하면 View를 그려줄 때 마다 객체를 생성하게 됩니다.

@ObservedObject private var viewModel : LandMarkViewModel = LandMarkViewModel()

 

만약 의존성 주입 방식이 싫다고 한다면 @StateObject를 통해 이 객체는 한번만 생성한다라고 알려주면 됩니다.

@StateObject private var colorHelper = ColorHelper()

자세한 내용은 해당 사이트에 잘 정리 되어 있습니다.

(https://medium.com/hcleedev/swift-observedobject%EC%99%80-stateobject-4f851ed9ef0d)

 

- EnvironmentObject -

EnvironmentObject는 환경변수로 선언된 객체를 싱클톤과 같은 느낌으로 가져와서 사용할 수 있게 됩니다.

@EnvironmentObject var colorHelper : ColorHelper

따로 init()을 통해서 값을 넘겨 받는 것이 아니라

가장 최상단 또는 해당 변수를 사용하기 상위 View에서 environmentObject 메소드를 통해서 넣어주면 됩니다.

 @StateObject private var colorHelper = ColorHelper()
    var body: some Scene {
        WindowGroup {
            MainView(viewModel: LandMarkViewModel())
                .environmentObject(colorHelper)
        }
    }

만약 최상위 뷰에 위와 같이 해줬다면 따로 선언해줄 필요 없이 어디서든지 해당 객체에 접근이 가능해집니다. (싱글톤 느낌으로,,)

 

SwiftUI에서는 다양한 바인딩 기능을 제공해주고 있습니다.

따라서 MVVM이 맞나라는 생각이 들었습니다.

선언형 View 개발 시스템에서도 MVVM을 사용하는지 아니면 다른 아키텍처를 사용하는지 봐야 할 것 같습니다.

아카이브.zip
0.01MB

** 참고사이트 **

다양한 Binding 내용정리 :

https://medium.com/harrythegreat/swiftui-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC-5%ED%8E%B8-state-binding-observedobject-83c00c3317cb

 

SwiftUI 튜토리얼 5편 — @State, @Binding, @ObservedObject

다양한 바인딩 방법에대해 알아보기

medium.com

https://medium.com/hcleedev/swift-observedobject%EC%99%80-stateobject-4f851ed9ef0d

 

Swift: ObservedObject와 StateObject

SwiftUI의 ObservedObject와 StateObject가 무엇인지, 두 프로퍼티 래퍼에는 어떤 차이가 있는지 알아보자

medium.com

https://nsios.tistory.com/120

 

[SwiftUI] Published, ObservableObject

SwiftUI를 공부하다보면 @Published 라는 키워드를 보게될거에요 이와 같이 언급되는게 ObservableObject죠 ObservableObject는 필수구현을 필요로 하지않는 프로토콜이에요 Combine에 속한 기능이구요 클래스

nsios.tistory.com

 

- Binding 초기화 하는 벙법 :

https://stackoverflow.com/questions/56973959/swiftui-how-to-implement-a-custom-init-with-binding-variables

 

SwiftUI: How to implement a custom init with @Binding variables

I'm working on a money input screen and need to implement a custom init to set a state variable based on the initialized amount. I thought this would work, but I'm getting a compiler error of: Ca...

stackoverflow.com

https://stackoverflow.com/questions/57178382/cannot-assign-to-property-text-is-immutable

 

Cannot assign to property: '$text' is immutable

I wanted to make a custom textfield in SwiftUI to can handle first responder but I had this error in the code and struct is immutable I don't know what should I do? struct CustomTextField:

stackoverflow.com

 - Eviorment PropertyWrapper 

https://seons-dev.tistory.com/entry/SwiftUI-Environment-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0-%EB%9E%98%ED%8D%BC

 

SwiftUI : @Environment 프로퍼티 래퍼

Environment  에 대해 알아보도록 합시다. Environment 앞에서 다룬 Environment 수식어가 뷰의 환경 요소를 변경시키기 위한 쓰기 전용의 기능이었다면, 이번에 볼 @Environment 라는 프로퍼티 래퍼는 읽기

seons-dev.tistory.com

 

View를 Present하는 방법 : 

https://rhammer.tistory.com/370

 

SwiftUI에서 Modal을 Present하기

import SwiftUI struct ContentView: View { @State private var isPresented = false var body: some View { Button("Present!") { self.isPresented.toggle() } .fullScreenCover(isPresented: $isPresented, co..

rhammer.tistory.com

 

EmptyView 생성 방법 :

https://stackoverflow.com/questions/66129691/how-can-i-define-default-empty-input-content-for-a-view-in-swiftui

 

How can I define default empty input content for a View in SwiftUI?

I have CustomContentView() which I like give an empty content like {} as default to it, which I do not have to do it in use case, for example I done same thing for Color! more info: the answer could

stackoverflow.com

 

LazyV(H)Grid :

https://seons-dev.tistory.com/entry/SwiftUI-Grid

 

SwiftUI : Lazy V(H)Grid

목차 Grid 에 대해 알아보도록 합시다. Lazy V(H)Grid List와 Grid의 차이 Grid 는 List 와 친척이라고 생각하시면 됩니다. 일단 Grid 와 List 의 차이를 간단하게 그림으로 보겠습니다. LazyV(H)Stack 과의 차..

seons-dev.tistory.com

 

NavigationView : 

https://seons-dev.tistory.com/entry/NavigationView

 

SwiftUI : NavigationView / NavigationLink

목차 NavigationView  는 SwiftUI 의 가장 중요한 구성 요소 중 하나입니다. 화면을 쉽게 Push 와 Pop 할 수 있으며, 사용자에게 명확하고 계층적인 방식으로 정보를 제공할 수 있습니다 NavigationView Navigat.

seons-dev.tistory.com

- 화살표 방향 지우는 방법 

https://stackoverflow.com/questions/58333499/swiftui-navigationlink-hide-arrow

 

SwiftUI NavigationLink Hide Arrow

Is there a way to hide the arrow to the right of the navigation link view that is automatically added? I want to show an image grid using NavigationView -> List -> HStack -> NavigationLink_1 -

stackoverflow.com

- Navigation바 에서 버튼 생성 

https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-a-toolbar-and-add-buttons-to-it

 

How to create a toolbar and add buttons to it - a free SwiftUI by Example tutorial

Was this page useful? Let us know! 1 2 3 4 5

www.hackingwithswift.com

 

SwiftUI에서 SuperView Layout 잡는 방법 : 

https://stackoverflow.com/questions/56508403/how-to-make-width-of-view-equal-to-superview-in-swiftui

 

How to make width of view equal to superview in SwiftUI

I have Button struct ContentView : View { var body: some View { HStack { Button(action: {}) { Text("MyButton") .color(.white) ...

stackoverflow.com

https://stackoverflow.com/a/71073866

 

Invalid frame dimension (negative or non-finite)

Hey im new to this platform but swift is giving me a headache it is seeming to have a problem with the value (Infinity) although what should i put instead .bold() ...

stackoverflow.com

ScollView Offset:

https://www.fivestars.blog/articles/scrollview-offset/

 

SwiftUI ScrollView offset | FIVE STARS

SwiftUI ScrollView offset Searching online for "SwiftUI ScrollView offset" yields to plenty of discussions on how to control the scroll position of a ScrollView: with iOS 14 SwiftUI has gained ScrollViewReader, covered here, which makes the old introspecti

www.fivestars.blog

https://developer.apple.com/forums/thread/650312

 

Get position of scrollview | Apple Developer Forums

With the release of iOS 14, there is a new ScrollViewReader which seems like it can read the current position. However, the docs around this are minimal, and do not explain how to do so. So, what is ScrollViewReader, and how can I get the current position

developer.apple.com

GeometryReader : 

https://www.hackingwithswift.com/books/ios-swiftui/resizing-images-to-fit-the-screen-using-geometryreader

 

Resizing images to fit the screen using GeometryReader - a free Hacking with iOS: SwiftUI Edition tutorial

Was this page useful? Let us know! 1 2 3 4 5

www.hackingwithswift.com

https://medium.com/hcleedev/swift-geometryreader%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-564896c6d6e0

 

Swift: GeometryReader는 무엇일까?

알면 알 수록 헷갈리는 특이한 Container View, GeometryReader에 대해 알아보자.

medium.com

 

Dynamic Size 변경하는 방법: 

https://stackoverflow.com/questions/65603929/how-to-dynamically-size-an-image-in-swiftui-for-accessibility

 

How to dynamically size an image in SwiftUI for accessibility?

I have an image that I'm hard coding the size, but realized it's not scaling for larger size categories. How can I set a preferred size and let it scale up to different sizes automatically? This is...

stackoverflow.com

https://daddycoding.com/2020/06/17/swiftui-scaling-animation/

 

SwiftUI: Scaling Animation | DaddyCoding - Learn Swift, SwiftUI, iOS, RxSwift Programming

Animation on SwiftUI is a lot easier to achieve than UIKit with so much more support provided by Apple. I wonder if this will be a good thing or bad thing but regardless, we need to make good use of what is provided right. In this tutorial, you’ll learn

daddycoding.com

https://www.hackingwithswift.com/quick-start/swiftui/how-to-scale-a-view-up-or-down

 

How to scale a view up or down - a free SwiftUI by Example tutorial

Was this page useful? Let us know! 1 2 3 4 5

www.hackingwithswift.com

 

Divider 굵기 변경 :

https://stackoverflow.com/questions/58787180/how-to-change-width-of-divider-in-swiftui

 

How to change width of Divider in SwiftUI?

On few screens of my SwiftUI app I am using Divider() between few elements. This Divider is rendered as a very thin grey (or black?) line. I am guessing 1 point. How can I change the width of Divid...

stackoverflow.com

 

ZStack 위치 병경하는 벙법 : 

https://www.hackingwithswift.com/quick-start/swiftui/how-to-adjust-the-position-of-a-view-using-its-offset

 

How to adjust the position of a view using its offset - a free SwiftUI by Example tutorial

Was this page useful? Let us know! 1 2 3 4 5

www.hackingwithswift.com

 

ForEach에서 Index 얻는 방법 :

https://stackoverflow.com/questions/57244713/get-index-in-foreach-in-swiftui

 

Get index in ForEach in SwiftUI

I have an array and I want to iterate through it initialize views based on array value, and want to perform action based on array item index When I iterate through objects ForEach(array, id: \.se...

stackoverflow.com

 

728x90
반응형

댓글