Skip to content

Instantly share code, notes, and snippets.

@oocoocococo
Created January 22, 2021 03:36
Show Gist options
  • Save oocoocococo/187061b6bcbebc10e7d1dc2eabb11f07 to your computer and use it in GitHub Desktop.
Save oocoocococo/187061b6bcbebc10e7d1dc2eabb11f07 to your computer and use it in GitHub Desktop.
import SwiftUI
@main
struct PetShopApp: App {
/// ペットショップ
@StateObject private var shop: PetShop = .init()
var body: some Scene {
WindowGroup {
ContentView(shop: shop)
}
}
}
struct ContentView: View {
/// ペットショップ
@ObservedObject var shop: PetShop
var body: some View {
NavigationView {
List {
ForEach(shop.dogs) { dog in
DogCell(dog: dog)
} // ForEach
.onMove(perform: moveDogs)
.onDelete(perform: deleteDog)
HStack {
Spacer()
Text("\(shop.dogs.count) dogs")
.foregroundColor(.secondary)
Spacer()
} // HStack
} // List
.navigationTitle("Dogs")
.toolbar {
#if os(iOS)
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
} // ToolbarItem
#endif
ToolbarItem(placement: .automatic) {
Button("Add", action: makeDog)
} // ToolbarItem
} // toolbar
Text("Select a dog")
.font(.largeTitle)
} // NavigationView
} // body
/// 犬を追加
func makeDog() {
withAnimation {
// ドーベルマンを追加
shop.dogs.append(.init(name: "Doberman", age: 1, popularity: false))
}
}
/// 犬を移動
func moveDogs(from: IndexSet, to: Int) {
withAnimation {
shop.dogs.move(fromOffsets: from, toOffset: to)
}
}
/// 犬を削除
func deleteDog(offsets: IndexSet) {
withAnimation {
shop.dogs.remove(atOffsets: offsets)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(shop: testShop)
}
}
/// 犬セル
struct DogCell: View {
/// 犬情報
let dog: Dog
var body: some View {
NavigationLink(destination: DogDetail(dog: dog)) {
Image(dog.thumbnailName)
.resizable()
.frame(width:40, height: 40)
.aspectRatio(contentMode: .fill)
.cornerRadius(8.0)
VStack(alignment: .leading) {
Text(dog.name)
Text("\(dog.age) years old")
.font(.subheadline)
.foregroundColor(.secondary)
} // VStack
} // NavigationLink
} // body
}
struct DogCell_Previews: PreviewProvider {
static var previews: some View {
DogCell(dog: testData[0])
.previewLayout(.sizeThatFits)
}
}
/// 犬詳細画面
struct DogDetail: View {
/// 犬情報
let dog: Dog
/// ズームした
@State private var zoomed: Bool = false
var body: some View {
VStack {
Spacer(minLength: 0)
Image(dog.imageName)
.resizable()
.aspectRatio(contentMode: zoomed ? .fill : .fit)
.onTapGesture {
withAnimation {
zoomed.toggle()
}
}
Spacer(minLength: 0)
if dog.popularity && !zoomed {
HStack {
Spacer()
Label("Popularity", systemImage: "star.fill")
Spacer()
} // HStack
.padding(.all)
.font(Font.headline.smallCaps())
.background(Color.red)
.foregroundColor(.yellow)
.transition(.move(edge: .bottom))
}
} // VStack
.edgesIgnoringSafeArea(.bottom)
.navigationTitle(dog.name)
} // body
}
struct DogDetail_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
DogDetail(dog: testData[0])
}
}
}
/// ペットショップ
class PetShop: ObservableObject {
@Published var dogs: [Dog]
init(dogs: [Dog] = []) {
self.dogs = dogs
}
}
/// テストショップ
let testShop: PetShop = PetShop(dogs: testData)
/// 犬モデル
struct Dog: Identifiable {
/// ID
var id:UUID = UUID()
/// 名前
var name: String
/// 年齢
var age: Int
/// 人気
var popularity: Bool
/// 画像名
var imageName: String {
name
}
/// サムネイル画像名
var thumbnailName: String {
name + "Thumb"
}
}
/// テストデータ
let testData: [Dog] = [
.init(name: "Kaiken", age: 2, popularity: false),
.init(name: "Great Pyrenees", age: 2, popularity: true),
.init(name: "Akitainu", age: 1, popularity: false),
.init(name: "Doberman", age: 3, popularity: false),
.init(name: "Shetland Sheepdog", age: 1, popularity: false),
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment