Tabview

  • Tab을 만들어 각각의 view 마다 다른 화면을 보여주는것
Tabview {
	View()
		.tabItem {
		//- tabItem 의 내용 이미지, 이름 등을 설정
	}
}
  • tabItem에는 Label , Text, Image 만 허용하고, Button 과 같은 컴포넌트가 포함되면 해당 뷰는 빈 페이지로 로드

Data

  • Model 개념의 구조체로 데이터의 ‘청사진' 을 구성
struct Info {
    let image: String
    let name: String
    let story: String
    let hobbies: [String]
    let foods: [String]
    let colors: [Color]
    let funFacts: [String]
}
  • 해당 데이터의 모델 구성하면, 앱의 전반적인 곳에서 해당 모델을 사용할 수 있음
let information = Info(
    image: "Placeholder",
    name: "My Name",
    story: "A story can be about anything you can dream up. There are no right answers, there is no one else.\\n\\nNeed some inspiration?\\n• 🐶🐱🛶️🎭🎤🎧🎸\\n• 🏄‍♀️🚵‍♀️🚴‍♀️⛵️🥾🏂⛷📚\\n• ✍️🥖☕️🏋️‍♂️🚲🧗‍♀️ ",
    hobbies: ["bicycle", "ticket.fill", "book.fill"],
    foods: ["🥐", "🌮", "🍣"],
    colors: [Color.blue, Color.purple, Color.pink],
    funFacts: [
        "The femur is the longest and largest bone in the human body.",
        "The moon is 238,900 miles away.",
        "Prince’s last name was Nelson.",
        "503 new species were discovered in 2020.",
        "Ice is 9 percent less dense than liquid water.",
        "You can spell every number up to 1,000 without using the letter A.\\n\\n...one, two, three, four...ninety-nine...nine hundred ninety-nine 🧐",
        "A collection of hippos is called a bloat.",
        "White sand beaches are made of parrotfish poop.",
    ]
)

View 의 구성

  • VStack 은 컴포넌트 들을 수직으로 정렬
  • Text 를 사용해서 글을 표시할수 있으며 .font / .fontWeight 등의 옵션으로 글을 커스텀 할수 있음
  • padding 을 사용하여 다른 뷰와의 거리를 띄울수 있음
  • Image 를 사용해서 이미지를 추가 할수 있다
    • .resizable() 을 사용하여 이미지의 크기를 조절 할 수 있다
    • .aspectRatio(contentMode: .fit) 을 사용하여 이미지의 종횡비를 지정할 수 있다.
    • .cornerRadius() 를 사용하면 이미지의 모서리를 둥글게 할수 있다.
Imgae("이미지 내용")
  • ScrollView
    • ScrollView 를 구성 하려면 ScrollView { ... } 로 감싸면 된다 
ScrollView { Text(information.story) .font(.body) .padding() }
  • HStack 은 컴포넌트 들을 수평 으로 정렬
  • ForEach 구문을 사용하여 뷰를 구성할 수 있다.
    • id: \.self 를 통해 고유 값을 설정한다 ( 인덱스의 개념! )
ForEach(information.hobbies, id: \\.self) { hobby in 
	Image(systemName: hobby) 
    	.resizable() 
        .frame(maxWidth: 80, maxHeight: 60) 
}
  • @State 를 사용하면 내용이 바뀔때마다 view 를 새로 그린다
  • Button 클로저 아래에 여러 설정값으로 버튼의 모양을 변경할 수 있다
Button("Show Random Fact") { 
	funFact = information.funFacts.randomElement()! 
    } 
    .padding() 
    .background(Color.cyan) 
    .cornerRadius(20)

 

SwiftUI에서 어떠한 view는 View 프로토콜을 준수해야 한다

protocol View {
	associatedtype Body: View
    	var body: Self.Body { get }
}

 

=> 프로토콜을 보면 알 수 있듯, 필수로 구현해 줘야 하는것은 연산프로퍼티인 읽기 전용 body 임을 알 수 있음

 

Text, Image, Color, Stack, Group, GeometryReader 등의 컨텐츠나 컨테이너 뷰에는 더이상 Body를 호출하지 않게 Never 타입을 사용

typealias Body = Never

 

1. 선언형

명령형 vs 선언형

명령형

UIKit 의 경우 명령형 선언으로써, 방법(How)에 초점을 두어 코드를 서술한다.

1) 버튼을 생성

2) 버튼의 제목 설정

3) 버튼 제목의 색상 설정

4) 폰트 지정

5) 버튼 클릭시 호출할 메서드 지정

6) 루트 뷰에 자식 뷰를 추가

7) 버튼을 화면 가운데로 배치

 

선언형

SwiftUI의 경우 선언형 선언으로써, 무엇(What)에 초첨을 두어 코드를 서술

Button(action: {
	print("Hello, SwiftUI")
}) {
	Text("SwiftUI")
    	.font(.title)
        .foregroundColor(.black)
}

=> 버튼을 생성하는데 버튼의 글자는 "SwiftUI" 이고, 폰트는 title, 색상은 검정색, 클릭했을때는 "Hello, SwiftUI"를 출력해줘

 

2. 자동화

=> 가능한 많은 기능이 자동으로 수행될 수 있게 제공하는것

자동화를 통하여 화면에 뷰를 배치할 오토 레이아웃 코드를 제거하고 최소한의 설명으로 적용할 수 있게 되었음

3.  조합

=> 큰 뷰를 하나의 기능을 가진 작은 뷰들로 잘게 나누거나 각각의 뷰를 조합해 원하는 뷰를 쉽게 만들어 낼수 있게 지원

4. 일관성

=> 데이터와 동기화되어 일관성 있게 보여줘야함

1) 데이터가 변경되면 그에 맞게 UI도 변경되어야함

2) 데이터가 변경되는 즉시 UI도 자동 갱신

3) 뷰의 특정 상태를 저장할 State / 모델 객첼의 변화를 관찰할 ObservableObject 로 인하여 데이터의 변화를 감지, UI 갱신

 

+ Recent posts