Skip to content

Instantly share code, notes, and snippets.

@pardeike
Last active August 29, 2019 18:47
Show Gist options
  • Save pardeike/00b63f7c8e11b7b86ee08144d7ffa465 to your computer and use it in GitHub Desktop.
Save pardeike/00b63f7c8e11b7b86ee08144d7ffa465 to your computer and use it in GitHub Desktop.
import SwiftUI
class Person: Hashable {
var uuid = UUID().uuidString
var name: String = ""
var toys: [Toy]
init(name: String, _ toys: Toy...) {
self.name = name
self.toys = toys
}
func copy() -> Person {
let p = Person(name: name)
p.toys = toys
return p
}
func minToy() -> Toy? {
return toys.sorted { $0.rating < $1.rating }.first
}
func maxRating() -> Int {
return toys.map({ $0.rating }).max() ?? -1
}
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.uuid == rhs.uuid
}
func hash(into hasher: inout Hasher) {
hasher.combine(uuid)
}
}
class Toy: Hashable {
var uuid = UUID().uuidString
var name: String = ""
var rating: Int
init(name: String, rating: Int) {
self.name = name
self.rating = rating
}
func copy() -> Toy {
return Toy(name: name, rating: rating)
}
static func == (lhs: Toy, rhs: Toy) -> Bool {
return lhs.uuid == rhs.uuid
}
func hash(into hasher: inout Hasher) {
hasher.combine(uuid)
}
}
struct PersonRow: View {
var person: Person
var body: some View {
VStack(alignment: .leading) {
HStack {
Text(person.name).bold()
Spacer()
Text("toys:\(person.toys.count)")
Text("max-rating:\(person.maxRating())")
}
HStack {
ForEach(person.toys, id: \.self) { toy in
Text("\(toy.name)[\(toy.rating)]")
.font(Font.caption)
}
}
}
}
}
struct ContentView: View {
@State var persons: Array<Person>
@State var idx: Double
func AddToys_A() {
let n = Int(idx)
persons[n].toys.append(Toy(name: "Stuff", rating: 0))
}
func AddToys_B() {
let n = Int(idx)
let newPerson = persons[n].copy()
newPerson.toys.append(Toy(name: "Stuff", rating: 0))
persons[n] = newPerson
}
func ToyRating() {
if let minPerson = persons.sorted(by: { ($0.minToy()?.rating ?? -1) < ($1.minToy()?.rating ?? -1) }).first {
if let n = persons.firstIndex(of: minPerson) {
let p = persons[n].copy()
if let toy = p.toys.sorted(by: { $0.rating < $1.rating }).first {
toy.rating += 1
}
persons[n] = p
}
}
}
func AddPerson() {
let p = Person(name: "\(Int(Date().timeIntervalSince1970))")
p.toys.append(Toy(name: "New", rating: 0))
persons.append(p)
}
func Reset() {
persons.removeAll()
persons.append(Person(name: "Johan", Toy(name: "Docka", rating: 3)))
persons.append(Person(name: "Elin", Toy(name: "Cykel", rating: 5), Toy(name: "Båll", rating: 4)))
persons.append(Person(name: "Bengt", Toy(name: "Bil", rating: 1)))
}
var body: some View {
NavigationView {
VStack {
VStack {
Slider(value: $idx, in: 0...5)
.frame(height: 40)
HStack {
Spacer()
Button(action: AddToys_A) {
Text("\(Int(idx))+toys (A)")
}
Spacer()
Button(action: AddToys_B) {
Text("\(Int(idx))+toys (B)")
}
Spacer()
}
HStack {
Button(action: ToyRating) {
Text("bump rating")
}
Spacer()
Button(action: AddPerson) {
Text("new person")
}
Spacer()
Button(action: Reset) {
Text("reset")
}
}
}
.padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10))
List {
ForEach(persons, id: \.uuid) { person in
PersonRow(person: person)
}
}
}
.navigationBarTitle("Persons and toys")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var data: Array<Person> = [
Person(name: "Johan", Toy(name: "Docka", rating: 3)),
Person(name: "Elin", Toy(name: "Cykel", rating: 5), Toy(name: "Boll", rating: 4)),
Person(name: "Bengt", Toy(name: "Bil", rating: 1))
]
static var previews: some View {
ContentView(persons: data, idx: 0)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment