Introducing SwiftUI: Building Your First App ・Rooms

# WWCD2019のセッション204を再現しての話 ? 警告の嵐 ?

[引用先・WWDC2019 204 Rooms by Apple](https://developer.apple.com/videos/play/wwdc2019/204/)

>2019/10/29 PM16:33 更新します、内容 : 以下の問題は解決しました、サムネイルの「Hall 2Thumb.jpg」の画像サイズが100X100ピクセルと他は64X64とかでした、このセル画像はサイズに影響があるのですね ? 知らなかった ?
2019/10/28 PM22:00 追伸です、このコードではセルを追加するAdd RoomをタップするとHall2のアイコンがデカいんですよね ? 解決方法が分からないのでこのまま投稿しました、解決したら修正します ? 一体、どうするねん ?

- 以下からは元の投稿です

> 動画の通りに再現しましたがダメでした ? しかし、動くようになりました ?

編集箇所前のコードはコメントしています

ファイルの数は4種類

- ContentView.swift
- Room.swift
- RoomDetail.swift
- RoomStore.swift

動画の後半の多国語言語とかのコードは分からないので書いてません、それと20枚の画像 ?

- Rooms.xcassets

これはネットで探してください

これに悩んでる人なら以下のコードを見ればわかりますよ ? 解決っ ?

# ContentView.swift

```ContentView.swift

//
//  ContentView.swift
//  SwiftUITest
//
//  Created by 福田 敏一 on 2019/10/27.
//  Copyright © 2019 株式会社パパスサン. All rights reserved.
//

import SwiftUI

struct ContentView: View {
//@ObjectBinding var store = RoomStore()
    @ObservedObject var store = RoomStore()
        
    var body: some View {
        NavigationView {
            List {
                Section {
                    Button(action: addRoom) {
                        Text("Add Room")
                    }
                }
                
                Section {
                    ForEach(store.rooms) { room in
                        RoomCell(room: room)
                    }
                    .onDelete(perform: delete)
                    .onMove(perform: move)
                }
            }
            .navigationBarTitle(Text("Rooms"))
            .navigationBarItems(trailing: EditButton())
//.listStyle(.grouped)
            .listStyle(GroupedListStyle())
        }
    }

    func addRoom() {
        store.rooms.append(Room(name: "Hall 2", capacity: 2000))
    }
    
    func delete(at offsets: IndexSet) {
        store.rooms.remove(atOffsets: offsets)
    }
    
    func move(from source: IndexSet, to destination: Int) {
        store.rooms.move(fromOffsets: source, toOffset: destination)
    }
}

    struct RoomsContentView_Previews: PreviewProvider {
        static var previews: some View {
            Group {
            RoomsContentView(store: RoomStore(rooms: testData))
            RoomsContentView(store: RoomStore(rooms: testData))
                .environment(\.sizeCategory, .extraExtraExtraLarge)
            RoomsContentView(store: RoomStore(rooms: testData))
                .environment(\.colorScheme, .dark)
            }
        }
    }

struct RoomCell: View {
    let room: Room
    
    var body: some View {
//return NavigationButton(destination: RoomDetail(room: room)) {
        return NavigationLink(destination: RoomDetail(room: room)) {
            Image(room.thumbnailName)
                .cornerRadius(8)
            
            VStack(alignment: .leading) {
                Text(room.name)
                Text("\(room.capacity) people")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
        }
    }
}


```

# Room.swift

```Room.swift

//
//  Room.swift
//  SwiftUITest
//
//  Created by 福田 敏一 on 2019/10/27.
//  Copyright © 2019 株式会社パパスサン. All rights reserved.
//

import SwiftUI

struct Room: Identifiable {
    var id = UUID()
    var name: String
    var capacity: Int
    var hasVideo: Bool = false
    
    var imageName: String { return name }
    var thumbnailName: String { return name + "Thumb"}
}

let testData = [
    Room(name: "Observation Deck", capacity: 6, hasVideo: true),
    Room(name: "Executive Suite", capacity: 8, hasVideo: false),
    Room(name: "Charter Jet", capacity: 16, hasVideo: true),
    Room(name: "Dungeon", capacity: 10, hasVideo: true),
    Room(name: "Panorama", capacity: 12, hasVideo: false),
    Room(name: "Oceanfront", capacity: 8, hasVideo: false),
    Room(name: "Rainbow Room", capacity: 10, hasVideo: true),
    Room(name: "Pastoral", capacity: 7, hasVideo: false),
    Room(name: "Elephant Room", capacity: 1, hasVideo: false),
]


```

# RoomDetail.swift

```RoomDetail.swift

//
//  RoomDetail.swift
//  SwiftUITest
//
//  Created by 福田 敏一 on 2019/10/27.
//  Copyright © 2019 株式会社パパスサン. All rights reserved.
//

import SwiftUI

struct RoomDetail: View {
    let room: Room
    @State private var zoomed = false
    
    var body: some View {
        ZStack(alignment: .topLeading) {
        Image(room.imageName)
            .resizable()            .aspectRatio(contentMode: zoomed ? .fill : .fit)
            .navigationBarTitle(Text(room.name), displayMode: .inline)
//.tapAction { withAnimation(.basic(duration: 2)) { self.zoomed.toggle() }}
            .onTapGesture { withAnimation(.easeInOut(duration: 2)) { self.zoomed.toggle() }}
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            
            if room.hasVideo && !zoomed {
                Image(systemName: "video.fill")
                    .font(.title)
                    .padding(.all)
                    .transition(.move(edge: .leading))
            }
        }
    }
}

struct RoomDetail_Previews: PreviewProvider {
    static var previews: some View {
        Group {
        NavigationView {RoomDetail(room: testData[0]) }
        NavigationView {RoomDetail(room: testData[1]) }
        }
    }
}


```

# RoomStore.swift

> 2019/11/17 コードを変更しました、意味不明ですが ? 少し能書き ?

- didSet -> willSet
- さらに@Publishedは必要 ?
- @Publishedを使うとwillSetとか ? 省略可能なの ?

> 変更箇所

```変更後のRoomStore.swift

//
//  RoomStore.swift
//  SwiftUITest
//
//  Created by 福田 敏一 on 2019/10/28.
//  Copyright © 2019 株式会社パパスサン. All rights reserved.
//

import SwiftUI
import Combine

class RoomStore : ObservableObject {
    
    @Published var rooms: [Room] /*{
        didSet { didChange.send() }
    }*/
    
    init(rooms: [Room] = []) {
        self.rooms = rooms
    }
    
//var didChange = PassthroughSubject<Void, Never>()
}


```

> 変更箭


```RoomStore.swift

//
//  RoomStore.swift
//  SwiftUITest
//
//  Created by 福田 敏一 on 2019/10/28.
//  Copyright © 2019 株式会社パパスサン. All rights reserved.
//

import SwiftUI
import Combine

//class RoomStore : BindableObject {
class RoomStore : ObservableObject {
//var rooms: [Room] {
    @Published var rooms: [Room] {
        didSet { didChange.send() }
    }
    
    init(rooms: [Room] = []) {
        self.rooms = rooms
    }
    
    var didChange = PassthroughSubject<Void, Never>()
}


```

ここまで

# 私の感想

> 私の感想ですが ?
ネットにあるSwiftUIの記事は古いです、ベータ版の話でしょうか ?
正規版では変更箇所があるようです、これはエラーも警告も出ないのですよ、だから最後まで悩んだのはRoomStore.swiftの15行目の @Published ですよ、偶然にも解決方法を発見しました、また、16行目のdidSet { didChange.send()はwillsetで作動しますが私には意味不明なので元のdidSetのままです、SwiftUIはまた一つ新しい言語を学んでいるような気がします、また、私の使用しているMacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)では重さを感じます