I am trying to recreate the SwiftUI project demonstrated in Session 204 but am running into some peculiar issues.
I wrote this from watching the session found here: https://developer.apple.com/videos/play/wwdc2019/204
Here is my code-
ContentView.swift:
import SwiftUI
struct ContentView : View {
@ObjectBinding var store = RoomStore()
var body: some View {
NavigationView {
List {
Section {
Button(action: addRoom) {
Text("Add Room")
}
}
Section {
ForEach(store.rooms) { room in //Error: Cannot convert value of type '(Room) -> RoomCell' to expected argument type '(_) -> _'
RoomCell(room: room)
}
.onDelete(perform: delete)
.onMove(perform: move)
}
}
.navigationBarTitle(Text("Rooms") )
.NavigationBarItems(trailing: EditButton())
.listStyle(.grouped)
}
}
func addRoom() {
store.rooms.append(Room(name: "Hall 2", capacity: 2000))
}
func delete(at offsets: IndexSet) {
store.rooms.remove(atOffsets: offsets) //Error: Incorrect argument label in call (have 'atOffsets:', expected 'at:')
}
func move(from source: IndexSet, to destination: Int) {
store.rooms.move(fromOffsets: source, toOffset: destination) //Error: Value of type '[Room]' has no member 'move'; did you mean 'remove'?
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
Group {
ContentView(store: RoomStore(rooms: testData))
ContentView(store: RoomStore(rooms: testData))
.environment(\.sizeCategory, .extraExtraExtraLarge)
ContentView(store: RoomStore(rooms: testData))
.environment(\.colorScheme, .dark)
ContentView(store: RoomStore(rooms: testData))
.environment(\.layoutDirection, .rightToLeft)
.environment(\.locale, Locale(identifier: "ar"))
}
}
}
#endif
struct RoomCell : View {
let room: Room
var body: some View {
return NavigationButton(destination: RoomDetail(room: room) )
{
Image(room.thumbnailName)
.cornerRadius(8)
VStack(alignment: .leading) {
Text (room.name)
Text ("\(room.capacity) peopje")
.font(.subheadline)
.foregroundColor(.secondary)
}
}
}
}
Room.swift:
import SwiftUI
struct Room {
var id = UUID()
var name: String
var capacity: Int
var hasVideo: Bool = false
var imageName: String { return name }
var thumbnailName: String { return name + "Thumb" }
}
#if DEBUG
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),
]
#endif
RoomDetail.swift:
import SwiftUI
struct RoomDetail : View {
let room: Room
@State private var zoomed = false
var body: some View { //Error: Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type
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() } }
}
.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) )
}
}
}
#if DEBUG
struct RoomDetail_Previews : PreviewProvider {
static var previews: some View {
Group {
NavigationView { RoomDetail(room: testData[0]) }
NavigationView { RoomDetail(room: testData[1]) }
}
}
}
#endif
RoomStore.swift:
import SwiftUI
import Combine
class RoomStore : BindableObject {
var rooms: [Room] {
didSet { didChange.send(Void()) } //Solved
}
init(rooms: [Room] = []) {
self.rooms = rooms
}
var didChange = PassthroughSubject<Void, Never>()
}
Error messages included in context, as comments, in above code.
Declarative vs Imperative Programming. Like Java, C++, PHP, and C#, Swift is an imperative programming language. SwiftUI, however, is proudly claimed as a declarative UI framework that lets developers create UI in a declarative way.
OpenSwiftUI is an OpenSource implementation of Apple's SwiftUI DSL (Domain-specific language). The project's goal is to stay close to the original API as possible. Currently, this project is in early development.
SwiftUI 3 is still in beta and will become available with iOS 15 and Xcode 13. There is much more to SwiftUI 3 than can be covered here, so do not miss the What's new in SwiftUI video from WWDC 2021 if you are interested.
SwiftUI is Apple's brand new framework for building user interfaces for iOS, tvOS, macOS, and watchOS. Apple introduced SwiftUI in 2019 and the framework has been evolving at a rapid pace ever since.
For this error: //Error: Cannot convert value of type '(Room) -> RoomCell' to expected argument type '(_) -> _' Implement Identifiable protocol to your list model like this,
struct Room: Identifiable
For this one: //Error: Incorrect argument label in call (have 'atOffsets:', expected 'at:') I think it is not your problem :) But you can use something like this,
guard let index = Array(offset).first else { return }
store.rooms.remove(at: index)
And for this one: //Error: Value of type '[Room]' has no member 'move'; did you mean 'remove'? As before, you can use that piece of code for moving
guard let sourceIndex = Array(source).first else { return }
store.rooms.insert(roomStore.rooms.remove(at: sourceIndex), at: destination)
You can check completed source code, https://github.com/ilyadaberdil/iOS-Samples/tree/master/SwiftUI-Sample
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With