Swift Lecture - 1

SEUNGHWANLEE·2021년 9월 16일
0

Swift

목록 보기
1/3
post-thumbnail

CS193p Developing Apps for iOS, Standford University 강의 👉

Lecture 1-2

  • Getting Started With SwiftUI
  • Learning More about SwiftUI

첫 번째 강의에서는 교수님이 Swift에 대한 전반적인 설명과 앱을 어떻게 만드는 지에 대해서 설명해주셨다.

UI를 만드는 것을 시작으로 iOS Application을 build하기 위해 사용하는 툴인 Xcode 사용방법과 활용도를 설명해주셨고, UI Component를 LEGO에 비유해서 더 직관적으로 이해하기 쉬웠다.

Process while building View

예를 들어서 집을 짓기 위해서는 안에 거실, 주방, 화장실 등이 필요하다. 그리고 주방을 만들기 위해서는 싱크대, 서랍, 테이블 등이 필요하고 또한 테이블을 만들기 위해서는 여러 블럭들이 필요하다.

이렇게 여러 Block들이 Stack + Wrap 되면서 하나의 View가 탄생하게 된다. View 안에는 View처럼 행동(behave like ~)하는 것들이 있을 것이고 이를 감싸주는 (Wrapping) 해주는 Combiners이 필요하다.

저는 개인적으로 Flutter를 약 1년동안 사용하고 처음 Swift를 배우는 입장에서 UI Component를 이해하는 데 크게 어려운 점이 없었어요 굉장히 비슷합니다 🤩 그럼 이제부터 수업에서 다뤘던 용어를 집중적으로 정리해보겠습니다.


첫 번째 Lecture는 UI를 중점으로 이루어집니다.

import SwiftUI // import when we build UI

UI

struct

  • variable들의 collection
  • 추가로 function들도 struct안에 위치할 수 있다
  • inheritence(상속성)이 없다
  • Swift는 object-oriented programming과 functional programming 모두 지원하지만 model, logic 그리고 UI를 만들때는 되도록이면 functional programming으로 짜는 것을 권장한다

View

  • :View 라는 뜻은 "it behaves like View"로 읽을 수 있다
  • View의 역할을 해준다는 뜻
  • View는 화면 내에 사각형, 즉 화면을 가리키는 것(ContentView.swift밖에 존재하지 않음)
  • View안에서 Taps, Swipe, Pinch등을 표현할 수 있음
  • Every Components mean `View``
struct ContentView: View {
...
}

위처럼 사용할 수 있는데, 맨 첫줄처럼 사용하는 방법이 선언하는 방법이다. :과 함께 사용한다면 type을 명시해주는 것과 같지만 Swift는 compiler가 자동으로 초기화 될 때나 assign될 때 값을 보고 type을 정하기 때문에

var i: Int

위와 같이는 자주 사용하지 않는다. 항상 readability를 생각해서 코드를 작성하는 습관을 갖는게 중요하다 😎

some

가장 생소했던 것 중 하나

  • Dart에서 사용하던 dynamic과 비슷한 느낌이 들면서 아닌 듯 하다..🥲
var body: some View {
	ZStack { ...
    }
}

코드를 보면 var body: some View로 body가 선언되어있다. 이때 body는 compiler에게

"나는 어떤(some) View 를 반환(return)할꺼야 그러니 호출(call)될 때 맨 뒤에 function({ })안에 뭐가 오는지 확인해줘"

라고 하는 것과 같다. 그리고 실제로 메모리에 저장되어있는 것이 아니라 호출이 될 때 body안에 있는 것을을 return 한다. functional programming을 하고있는 모습 🔥

  • 위에서 말한 LEGO를 생각해보면 작은 조각들(pieces)을 모아서 하나의 Component로 만들어 주는 Combiner 역할을 주로 한다.

Swift에서 흥미로웠던 것은 마지막 attribute를 선언하지 않고 { }으로 대체할 수 있다는 점이다. 예를 들어서,

ZStack(content: {
	Text("Placeholder")
})

ZStack을 Xcode내에서 쓰면 다음과 같이 자동완성을 해주는데, content 내에 작성할 필요없이 마지막 attribute라면 { }만으로도 아래와 같이 작성가능하다.

ZStack {
	Text("PlaceHolder")
}

이렇게 { }으로 감싸는 것은 function을 의미하며 결국 content 또한 function임을 알 수 있다.

Stack

ListView, GridView 와 같이 여러 Component를 나열할 때 사용된다.

  • VStack: Vertical Stack, 위에서
    아래로 Component를 배치할 때 사용
  • HStack: Horizontal Stack, 왼쪽에서 오른쪽으로 Component를 배치할 때 사용
  • ZStack: Z(x,y,z 처럼 3차원으로 생각하면 쉽다) Stack, 레이어를 쌓는 듯이 해서 Component를 모아서 배치할 때 사용

ScrollView

Flutter, Android와 다르게 가장 사용하기 편리했다.

  • default로 필요한 화면의 크기만 차지한다. 즉, ScrollView { }, 괄호안에 선언되어있는 Component의 크기만큼 화면 내에서 출력된다.

Spacer

  • alignment나 layout 조정할 때 자주 쓰일 것 같은 Component이다.
  • SwiftUI에서 자동으로 Center align과 균일하게 공간을 각 Component들이 차지하기 때문에 분할하거나 여유 공간을 넣고 싶을 때 사용하면 좋을 듯 하다.
  • "grabs all space"

Button

UI의 작은 부분도 functional programming으로 작성하는 편이 좋다. Xcode에서 Button을 입력하면 아래와 같이 나오게 되는데, action과 label을 사용해서 Button Component를 만들었다.

Button {
	if emojiCount > 1 {
    	emojiCount -= 1
	}
} label: {
	Image(systemName: "minus.circle")
}

첫 번째 { }안에 작성된 것이 action에 해당하고 두 번째 brace는 label이라고 explicitly 작성해야한다. action은 logic이 들어가면 된다.

Image

SF Symbols를 이용해서 여러 Icon을 사용할 수 있다. 사용하는 방법은 간단하다.

원하는 Icon의 이름을 확인한 뒤에 아래와 같이 작성해주면 assets에 추가하거나 할 필요없이 손쉽게 사용할 수 있다.

Image(systemName: "plus.circle")

LazyVGrid

  • 수천개의 Component가 안에 나열될 수 있지만 필요한 순간에만 build가 된다
  • 앱이 Portrait이거나 LandScape일 경우 종횡비가 서로 다르기 때문에 이를 잡아줄 수 있는 .adaptive를 사용하면 쉽게 적용할 수 있다
  • .adaptive()안에 minimummaximum을 선언해줄 수 있는데, 이때 넣어주는 값은 { }안에 오는 View의 각 수치(number)이다. 원형은 아래와 같다.
case adaptive(minimum: CGFloat, maximum: CGFloat = .infinity)

Control Flow

Range

  • 0...10: 0부터 10까지, 10 포함
  • 0..<10: 0부터 9까지, 10 미포함

ForEach

var emojis = ["😭", "🥺", "🧐", "😀", "😎", "🤨", "😵", "🥲", "😇"]
@State var emojiCount = 4
ForEach(emojis[0..<emojiCount], id: \.self) { emoji in
	CardView(content: emoji)
		.aspectRatio(2/3, contentMode: .fit)
}

emojisArray<String>, [String] 이므로 각 element는 identifiable하지 않다. 이번 강의에서는 약간의 cheat를 써서 emojis 내에 element를 모두 다른 게 initialize해서 ForEach안에 id: 값을 \.self로 선언해주었다. 이렇게 되면 각기 다른 element들로 구성되어있기 때문에 다른 성격을 띄게 된다.
그리고 사용하는 방법이 생소했다.

ForEach(emojis[0...<emojiCount], id: \.self) { emoji in
...
}

처럼 function 내에서 사용하는 element를 emoji in으로 선언해주어야한다. 어떻게 보면 ForEach부터 in까지 한 줄로 읽어보면 무슨 뜻인지 직관적으로 이해하기 쉽다.

@State

한 struct 내에 선언되어 있는 self.property는 immutable하다. 따라서 변경될 수 없다. 이럴 경우에는 @State를 variable앞에 선언해줘서 변경될 수 있도록 해준다.

변경이 될 때마다 View들은 새롭게 build되며 이에 대한 cost 관리도 해줘야 한다.

profile
잡동사니 😁

0개의 댓글