Range<Double>
import Foundation
let range : Range<Double> = 0.0..<5.0
0.0 .. < 5.0 은 0.0 이상 5.0 미만
0.0 ... 5.0 은 0.0 이상 5.0 이하
구조체가 Hashable 프로토콜을 채택하는 경우
- Hashable 프로토콜은 구조체나 클래스가 해시값을 가질 수 있도록 해주는 프로토콜
- 해시 값은 특정 객체를 빠르게 찾거나 비교할 때 사용하는데, Hashable을 채택한 구조체는 Set이나 Dictionary 같은 컬렉션에서 키로 사용할 수 있게 된다.
Identifiable 프로토콜
- 객체를 고유하게 식별할 수 있도록 해주는 프로토콜
- 이 프로토콜을 채택하면 객체마다 고유한 식별자를 가지게 되어, 컬렉션이나 리스트에서 특정 객체를 쉽게 찾거나 업데이트할 수 있다.
주요 조건은 다음과 같다.
1. id라는 이름의 프로퍼티를 !반드시! 가져야 한다. 이 id 프로퍼티는 고유한 식별자로서 보통 UUID나 기본타입(int, string)을 사용한다.
2. 프로토콜 선언 - Identifiable 프로토콜은 id 프로퍼티가 필요하다는 것만 명시할 뿐, 어떤 타입을 사용할 지는 지정하지 않는다. 따라서 id는 사용자 정의 타입도 사용이 가능하다.
AnyTransition 프로토콜
- 뷰가 화면에 나타나거나 사라질 때 사용할 전환 애니메이션을 정의
- 이 프로토콜을 사용한다면 다양한 사용자 정의 전환효과를 적용할 수 있다.
Swift UI는 몇가지 기본 전환 효과를 제공한다.
- 1. slide : 뷰가 슬라이드 하면서 나타나거나 사라지게
- 2. opacity : 뷰가 투명도 변화를 통해서 나타나거나 사라지게
- 3. scale : 뷰가 크기 변화를 통해 나타나거나 사라지게
var categories : [ String : [Landmark] ] {
Dictionary (
grouping : landmarks,
by : { $0.category.rawValue }
)
}
다음 코드를 풀어봐가며 살펴보자.
- 먼저 categories는 딕셔너리인데 키는 !문자열! 값은 !랜드마크배열!이다.
- 이 딕셔너리는 특정 기준에 따라서 그룹화된 Landmark 객체들을 저장한다.
- Dictionary(grouping : landmarks by : .. )
- 딕셔너리 초기화 메서드로서 landmarks 배열의 요소들을 그룹화한다.
- grouping : by : { $0.category.rawValue }는 그룹화의 기준이다.
- $0은 배열의 각 요소를 가리킨다.
코드로 살펴보면
import Foundation
struct Landmark : Identifiable, Codable{
var id : UUID
var name : String
var category : Category
}
enum Category : String, CaseIterable, Codable{
case lakes = "Lakes"
case rivers = "Rivers"
case mountains = "Mountains"
}
// 예제용 데이터
let landmarks = [
Landmark( id : UUID(), name = "Lake Tahoe", Category : .lakes ),
Landmark( id : UUID(), name = "Amazon River", Category : .rivers),
Landmark( id : UUID(), name = "Rocky Mountain", Category : .mountains),
Landmark( id : UUID(), name = "Nile River", Category : .rivers),
]
// 그룹화된 딕셔너리 생성
var categories : [ String : [Landmark] ] {
Dictionary(
grouping : landmarks,
by : { $0.category.rawValue }
// $0 === landmarks 각 요소인 Landmark 객체
)
}
// 결과 출력
for (category, landmarks) in categories{
print("\(category)")
for( landmark in landmarks ){
print(" ---- \(landmark.name)
}
}
이렇게 하면 출력은
Lakes :
- Lake Tahoe
Rivers :
- Amazon River
- Nile River
Mountains :
- Rocky Mountains
- category에 따라서 분류했기 때문에 Rivers에는 2개가 저장된다. 다시 말해서
호수 : 레이크 타호
강 : 아마존 강
산 : 로키 산
강 : 나일 강
에서
호수 : 레이쿠 타호
강 : 아마존, 나일 강
산 : 로키 산
이런식으로 묶이게 된다.
Swift Tutorials 4에 보면 다음과 같은 코드가 나온다.
import SwiftUI
struct CategoryHome: View {
@Environment(ModelData.self) var modelData
var body: some View {
NavigationSplitView{
Text("Hello world")
.navigationTitle("Featured")
} detail: {
Text("select a Landmark")
}
}
}
#Preview {
CategoryHome()
.environment(ModelData())
}
1. @Environment 프로퍼티 래퍼
- @Environment는 뷰가 특정 타입의 환경 데이터를 사용하도록 해주는 프로퍼티 래퍼이다.
- 예를 들어서, @Environment(ModelData.self) var modelData는 뷰가 ModelData 객체에 접근할 수 있게 한다.
2. #Preview 에 있는 .environment(ModelData())
- 프리뷰가 독립적인 테스트 환경을 제공하기 위함이다.
- 프리뷰는 CategoryHome이랑 같다고 생각하면 안된다.
- 별개로 동작하는 테스트용 화면이다.
ForEach와 id : .self
- ForEach는 SwiftUI에서 리스트나 컬렉션의 각 요소를 반복하여 뷰를 생성하는데 사용한다.
- 이 때 각 요소를 고유하게 식별할 수 있는 키를 제공해야하는데, id : \.self는 각 요소 자체를 식별자로 사용한다는 것이다.
'Ios > Swift UI' 카테고리의 다른 글
@Environment (0) | 2024.07.26 |
---|---|
Swift UI 메서드 정리 ( 계속 추가 ) (2) | 2024.07.24 |
@Environment로 커스템 데이터모델을 환경에서 가져오기 (4) | 2024.07.22 |
@Binding 과 .constant에 대해서 알아봅시다 (0) | 2024.07.22 |
키 패스 KeyPath 에 대해 알아봅시다 (2) | 2024.07.19 |