[TIL] SwiftUI

수빈·2022년 5월 1일
0

TIL

목록 보기
1/1
post-thumbnail

Stack

SwiftUi에서 사용하는 Stack의 종류는 3가지가 있는데 ZStack, HStack, VStack이다.

CS193p를 보며 카드 게임을 만들 수 있는데 제일 먼저 접한 Stack은 ZStack이었다.

ZStack

Gneric Structure, 요소를 오버레이하고 두 축으로 배열하는 뷰.

Text 4개를 겹쳤지만 화면에서는 하나로 보이는 상황. Stack이니 어딘가에 쌓여야 하는데 ZStack이라는 이름에 걸맞게 X, Y, Z 축으로 생각을 해 보면 Z축을 기준으로 Stack이 쌓인다고 보면 된다.

VStack, HStack

Vertical, Horisontal로 쌓이는 Stack이다.

이미지 출처

HStack이랑 VStack은 가로 쌓기, 세로 쌓기의 차이라서 더 서술하지 않으려고 한다.

ScrollView

화면의 Scroll 컨테이너를 쉽게 만들 수 있다. 내부에 배치한 내용에 맞게 자동으로 사이즈 조절이 가능하고, 안전 영역을 피하기 위해 필요한 요소도 자동으로 추가한다.

ScrollView{
	LazyVGrid(columns: [GridItem(.adaptive(minimum: 65))]) {
		ForEach(emojis[0..<emojiCount], id: \.self, content: { 
        	emoji in CardView(content: emoji)
            	.aspectRatio(2/3, contentMode: .fit)
         })
     }
}

Spacer

이름처럼 빈 공간을 만든다. 다른 Object의 크기에 우선 순위를 두고 해당 오브젝트의 크기가 변하지 않는 선에서 본인의 크기를 최대한 늘리려는 성질이 있다.

HStack {
	remove
    Spacer()
    add
}

가로로 쌓은 Stack을 Spacer()를 넣으니 각각의 버튼이 끝과 끝으로 멀어졌다.

SF-Symbols

위의 이미지에서 사용한 아이콘들은 아이폰 애플리케이션 UI에서 자주 쓰이는 아이콘인데 해당 아이콘을 모아둔 프로그램이 있다.

https://developer.apple.com/sf-symbols/

애플에서 제공하는 프로그램이다.

오른쪽 상단에 원하는 아이콘을 검색하면 여러 아이콘이 나온다.

    var remove: some View {
        Button {
            if emojiCount > 1 { emojiCount -= 1 }
        } label: {
            VStack {
                Image(systemName: "minus.circle") ⬅️
            }
        }
    }
    var add: some View {
        Button {
            if emojiCount < emojis.count { emojiCount += 1}
        } label: {
                VStack {
                     Image(systemName: "plus.circle") ⬅️
            }
        }
    }

⬅️ 표시 위치처럼 Image(systemName: "{sf-symbols 이름}" 으로 부여하면 된다. 사이즈 조절이나 색 부여도 가능하다

ForEach

카드 뒤집기 게임을 만들면서 아이콘 24개를 각 카드마다 부여를 해야 하는데 하나하나 지정하는 방법 말고 반복문을 통해 부여할 수 있다. C를 공부했을 때는 인자를 새로 선언해 반복문을 돌리는 게 번거로웠다면 SwiftUI에서는 스스로 본인 위치에 찾아가는 것 같은 느낌이었다.

일반적인 For과 ForEach가 다른 게 무엇이냐면 ForEach는 일종의 뷰 컨테이너처럼 작용하며, View를 계산해서 보여준다는 점이다.

ForEach(0..<10){ num in
    Text("Num: \(num)")
        .font(.largeTitle)
}

Int값이 아닌 String 배열을 ForEach에 넣으면 어떻게 될까 아마 오류가 날 것이다. 굳이 String이 아닌 Int 배열을 넣어도 똑같이 오류가 날 것.

이유는 Identifiable 프로토콜 조건에 맞지 않는다고 하는데. 해당 조건은 데이터를 식별할 수 있는 무언가를 가지고 있어야 한다고 한다. 각 배열마다 id를 가지고 있어야 한다고 이해하면 되겠다.

그렇다면 이 id는 어떻게 부여해야 할까? 직접 부여하는 방법도 있지만 배열의 개수가 10개 이상이어도 굉장히 귀찮아지는 일이다.

ForEach에서는 배열 내의 각 요소에 id를 부여할 수 있는 방법을 제공하는데

ForEach(emojis[0..<emojiCount], id: \.self, content: { emoji in
	CardView(content: emoji).aspectRatio(2/3, contentMode: .fit)
})

\ .self 를 입력하면 배열에서 각각의 요소에 아이디를 부여한다.

profile
42Seoul -soooh ~ 2022.04

0개의 댓글