본문 바로가기

IOS

3. IOS 강의 MVVM and the Swift Type System

 

www.youtube.com/watch?v=4GjXq2Sr55Q&feature=youtu.be

Assignment.pdf
0.07MB
Reanding.pdf
0.17MB
Slides.pdf
1.32MB

 

 

소스 

ContentView - view

//
//  ContentView.swift
//  Memorize
//
//  Created by user on 2021/01/15.
//

// UI 작업관련 패키지
import SwiftUI


// View Function
struct ContentView: View {
    
    var viewModel: EmojiMemoryGame
    
    var body: some View {
        HStack{
            ForEach(viewModel.cards) { card in
                CardView(card: card).onTapGesture {
                    viewModel.choose(card: card)
                }
            }
        }
        .padding()
        .foregroundColor(Color.orange)
        .font(Font.largeTitle)
        
    }
}

struct CardView: View {
    
    var card: MemoryGame<String>.Card
    
    var body: some View {
        ZStack {
            if card.isFaceUp {
                RoundedRectangle(cornerRadius: 10.0)
                    .fill(Color.white)
                
                RoundedRectangle(cornerRadius: 10.0)
                    .stroke(lineWidth: 3) // 테두리
                Text(card.content)
            } else {
                RoundedRectangle(cornerRadius: 10.0)
                    .fill()
            }
        }
    }
}




// Swift UI Preview 화면 띄우는 것
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(viewModel: EmojiMemoryGame())
    }
}

onTapGesture

www.hackingwithswift.com/books/ios-swiftui/how-to-use-gestures-in-swiftui

 

How to use gestures in SwiftUI - a free Hacking with iOS: SwiftUI Edition tutorial

Was this page useful? Let us know! 1 2 3 4 5

www.hackingwithswift.com

 

 

 

 

 

MemoryGame - model

//
//  MemoryGame.swift
//  Memorize
//
//  Created by user on 2021/01/16.
//

import Foundation

struct MemoryGame<CardContent> {
    var cards: Array<Card>
    
    func choose (card: Card){
        print("card chosen: \(card)")
    }
    
    init (numberOfPairsOfCards: Int, cardContentFactory: (Int)-> CardContent) {
        cards = Array<Card>()
        
        for pairIndex in 0 ..< numberOfPairsOfCards {
            
            let content = cardContentFactory(pairIndex)
            cards.append(Card(content: content, id:  pairIndex * 2))
            cards.append(Card(content: content, id: pairIndex * 2 + 1 ))
        }
        
    }
    
    
    struct Card: Identifiable {
        var isFaceUp: Bool = true
        var isMatched: Bool = false
        var content: CardContent 
        var id: Int
    }
    
}

Identifiable 프로토콜 

developer.apple.com/documentation/swift/identifiable

  • 항상 고유함을 보장합니다 (예 : UUID).

  • 환경마다 지속적으로 고유합니다 (예 : 데이터베이스 레코드 키).

  • 프로세스의 수명 동안 고유합니다 (예 : 전역 증분 정수).

  • 개체의 수명 동안 고유합니다 (예 : 개체 식별자).

  • 현재 컬렉션 내에서 고유합니다 (예 : 컬렉션 인덱스).

 

 

 

EmojiMemoryGame - modelAndView

//
//  EmojiMemoryGame.swift
//  Memorize
//
//  Created by user on 2021/01/16.
//

import SwiftUI

class EmojiMemoryGame {
    
    private(set) var model: MemoryGame<String> = EmojiMemoryGame.createMemoryGame()
    
    static func createMemoryGame() -> MemoryGame<String>{
        
        let emojis: Array<String> = ["😊", "😱", "😎"]
        
        return MemoryGame<String>(numberOfPairsOfCards: emojis.count) { parIndex in
            return emojis[parIndex]
        }
    }
        
    
    // MARK: - Access to the Model
    
    var cards: Array<MemoryGame<String>.Card> {
        model.cards
    }
    
    
    // MARK: - Intent(s)
    
    func choose(card: MemoryGame<String>.Card){
        model.choose(card: card)
    }
}

private(set) - get은 가능하고 set은 불가

 

 

struct (구조체), class

공통점

  • 여러 변수를 선언
  • 프로퍼티와 메서드를 사용
  • 프로토콜 사용 가능
  • 초기화를 정의하여 초기 상태를 설정 가능 (init)
  • 확장 ( extension ) 가능
  • 서브 스크립트 정의 가능
  • initializer 정의 가능

차이점

  • 구조체는 값 타입(메모리),  클래스는 참조타입
  • 구조체는 상속 불가, let으로 초기화 이후에 값 변경 불가
  • 클래스는 상속 가능, let으로 초기화 이후 값 변경 가능, deinitializer가 존재

 

구조체를 사용하는 경우

  • 불변성(Immutable)이 필요한 데이터 타입
  • 적은 데이터, 즉 멤버 프로퍼티의 갯수나 차지하는 메모리 용량이 적은 타입
  • 대입 보다는 생성되는 경우가 많은 타입
  • 공유될 필요가 없는 타입
  • 클래스 타입 등 레퍼런스에 기반한 자료형을 저장용 프로퍼티로 쓰지 않는 경우

 

Generics

모든 타입으로 작업 할수 있는 유연하고 제사용가능한 함수와 타입을 작성하는게 가능

정중복을 피하고 의도를 명확하고, 추상적으로 관리하는 코드를 작성 가능

제네릭은 Swift에서 가장 강력한 기능중에 하나

Swift 표준 라이브러리의 대부분은 제네릭 코드로 작성