THIS IS ELLIE

스탠포드 SwiftUI강의 복습하기 Lecture5 본문

개발/SwiftUI

스탠포드 SwiftUI강의 복습하기 Lecture5

Ellie Kim 2021. 2. 12. 22:34

접근제어자
접근제어자는 접근에 대한 권한을 지정하는 것.
다른 곳에서 접근할 필요가 없으면 private키워드를 붙여준다.
private(set) 키워드를 작성해 get만 가능하도록 할 수 있다.

private(set) var cards: Array<Card>

MemoryGame 모델에 cards변수에 private(set)을 지정해 뷰모델에서 접근만 가능하도록 한다.

// MARK: - Access to the model
var cards: Array<MemoryGame<String>.Card> {
    return model.cards
}

 

@ViewBuilder
some View를 리턴하는 모든 곳에는 해당 키워드@ViewBuilder를 넣을 수 있다.
Content는 뷰 리스트로 해석하고 하나로 결합한다.
여기서 하나의 뷰는 (2개에서 10개의 뷰) TupleView일수도 있고 (if-else가 존재하는 경우) ConditionalContent View일수도 있고 (아무것도 없는 경우) EmptyView일수도 있다. 그리고 이것들의 조합이 될 수도 있다.

@ViewBuilder이 표시된 함수 또는 변수의 contents는 뷰의 리스트로 해석된다.

@ViewBuilder

func front(of card: Card) -> some View {
	RoundedRectangle(cornerRadius: 10)
	RoundedRectangle(cornerRadius: 10).stroke()
	Text(card.content)
}

위는 TupleView를 리턴한다.

아래와 같이 뷰를 리턴하는 경우 파라미터에도 @ViewBuilder을 붙일 수 있다.

struct GeometryReader<Content> where Content: View { 
	init(@ViewBuidler content: @escaping (GeometryProxy) -> Content) { ... }
}

content 파라미터는 뷰를 반환하는 함수이다.
(ZStack, HStack, VStack, ForEach, Group도 모두 동일하게 작업을 수행)

 

Shape
Shape는 View를 상속한 프로토콜이다.
즉, 모든 Shape는 뷰다.
(SwiftUI Shape 예 : RoundedRectangle, Circle, Capsule 등)

이는 RoundedRectangle을 만든 코드이다.

RoundedRectangle(cornerRadius: cornerRadius).fill(Color.white)

fill() 함수를 살펴보면 이는 제네릭 함수이다.

func fill<S>(_ whatToFillWith: S) -> View where S: ShapeStyle

여기서 S는 ShapteStyle프로토콜을 따르는 모든 것이 될 수 있다.
예를 들어 Color, ImagePaint, AngularGradient, LinearGradient 등이 있다.

너만의 Shape를 만들고 싶다면 path를 구현해야 한다.

func path(in rect: CGRect) -> Path {
	return a Path 
}

여기에서 원하는 것을 그리는 Path를 만들고 반환한다.
Path에는 드로잉을 지원하는 수많은 기능이 있다.
선, 호, 베지에 곡선 등을 함께 추가하여 모양을 만들 수 있다.

 

ViewModifier
ViewModifier 프로토콜에는 하나의 기능이 있다.
이 함수의 유일한 작업은 전달된 항목을 기반으로 새 뷰를 만드는 것이다.
예를 들어 aspectRatio, Padding 등이 있다.

protocol ViewModifier {    
    func body(content: Content) -> some View { // Content는 dont care
		return some View that represents a modification of content
    }
}

content에 modification을 적용시킨 뷰 리턴함.

Text(“iOS”).modifier(Cardify(isFaceUp: true)) // eventually .cardify(isFaceUp: true)
struct Cardify: ViewModifier {
    var isFaceUp: Bool
    func body(content: Content) -> some View {
        ZStack {
            if isFaceUp {
                RoundedRectangle(cornerRadius: 10).fill(Color.white) 
                RoundedRectangle(cornerRadius: 10).stroke()
                content
            } else {
                RoundedRectangle(cornerRadius: 10)
            }
        }
    }
}

여기서 .modifier()은 ZStack안쪽이 리턴되는 것이다.
하지만 아래와 같이 사용하려면 따로 구현해줘야 한다.

Text(“iOS”).cardify(isFaceUp: true)

아래와 같이 구현해주면 위와 같이 호출할 수 있으며 어떤 뷰라도 사용할 수 있다.

extension View {
    func cardify(isFaceUp: Bool) -> some View {
        return self.modifier(Cardify(isFaceUp: isFaceUp))
    }
}

 


새로 추가된 코드

새로운 ViewModifier를 만들었다.

새로운 Shape를 만들었다.

뷰에 수정이 있었다.

결과적으로 텍스트 뒤에 파이 모양이 생겼다.

반응형