Swift UI에서 ForEach로 View 여러 개
오늘 스터디에서 날씨를 보여주는 페이지를 Swift UI로 구현하는 과제를 진행했다.
HStack과 VStack을 활용해서 구현하는 과제였고 구현 결과는 아래와 같다.
하지만 구현을 완료하고 보니 대부분이 하드 코딩되어 있어서 겹치는 코드들이 많아 이를 수정해주는 작업을 진행했다.
아래 사진을 보면 빨간색 뷰 안에 초록색 뷰들이 같은 형태로 배치되어 있는 것을 볼 수 있다.
기존에는 HStack 내부에 VStack을 여러 개 배치하는 방식으로 구현했는데, 이를 ForEach를 활용해서 VStack을 재사용하는 방식으로 수정했다.
1. 기존 코드
struct DailyHourWeatherView: View {
var body: some View {
HStack {
VStack {
Text("8AM")
Spacer()
Image(systemName: "sun.max.fill")
.foregroundColor(Color.yellow)
Spacer()
Text("63°")
}
VStack {
Text("9AM")
Spacer()
Image(systemName: "cloud.sun.fill")
Spacer()
Text("63°")
}
VStack {
Text("10AM")
Spacer()
Image(systemName: "sun.max.fill")
.foregroundColor(Color.yellow)
Spacer()
Text("64°")
}
VStack {
Text("11AM")
Spacer()
Image(systemName: "cloud.fill")
Spacer()
Text("61°")
}
VStack {
Text("12AM")
Spacer()
Image(systemName: "cloud.rain.fill")
Spacer()
Text("62°")
}
Spacer()
}
.font(.title3)
.frame(height: 120)
.padding()
}
}
2. 수정한 코드
struct DailyHourWeatherView: View {
var body: some View {
// ForEach를 사용해서 리펙토링 완료
// ForEach를 사용하기 위해선 전달인자로 전달하는 array의 각 element를 식별할 수 있는 id가 필요하다.
// 이를 위해 Weather 구조체가 Hashable을 만족하도록 구현했다.
HStack {
ForEach(weathers, id: \.self) { weather in
VStack {
Text(weather.time)
Spacer()
Image(systemName: weather.image)
Spacer()
Text(weather.temperature)
}
}
Spacer()
}
.font(.title3)
.frame(height: 120)
.padding()
}
}
리펙토링을 진행하면서 알게된 것은 ForEach를 활용할 때 전달인자로 전달하는 array의 각 요소를 식별할 수 있는 id를 넘겨줘야 하는 것을 발견했다. 그래서 Weather 구조체가 Hashable을 만족하도록 정의했다.
import Foundation
struct Weather : Hashable {
let id: Int
let time: String
let image: String
let temperature: String
}
'💻 개발 > iOS' 카테고리의 다른 글
[iOS / SwiftUI] 다양한 상태 프로퍼티들을 알아보자! (0) | 2022.10.24 |
---|---|
[iOS / SwiftUI] 키보드가 사라지지 않아요...😩 (0) | 2022.10.21 |
[iOS / Swift] lim 클로저 -> 0 (클로저, 극한으로 줄여보기) (0) | 2022.10.05 |
[iOS / Swift] 클로저와 프로퍼티, 가볍게 알아보기 (0) | 2022.10.02 |
[iOS / Swift] 상속 VS 익스텐션 (0) | 2022.09.27 |