Skip to content

Instantly share code, notes, and snippets.

@Koshimizu-Takehito
Created July 28, 2024 06:04
Show Gist options
  • Save Koshimizu-Takehito/e8e4ad74c04c584bea5f7d1092e26dfe to your computer and use it in GitHub Desktop.
Save Koshimizu-Takehito/e8e4ad74c04c584bea5f7d1092e26dfe to your computer and use it in GitHub Desktop.
Buttonがセルになるサンプル
import SwiftUI
struct ContentView: View {
@State private var show = false
@State private var items: [Item] = .samples()
var body: some View {
ScrollView {
LazyVStack {
ForEach(items.indices, id: \.self) { index in
let offset = Double(min(index, 20) + 1)
Button {
action(index: index, item: items[index])
} label: {
Row(item: items[index], index: index)
}
.buttonStyle(.borderedProminent)
.padding(.horizontal, 20)
.offset(y: show ? 0 : offset * 50)
.opacity(show ? 1 : 0)
.animation(.spring(duration: offset * 0.13), value: show)
}
}
}
.scrollIndicators(.hidden)
.task {
await fetch()
}
.refreshable {
await fetch()
}
}
func fetch() async {
withAnimation { show = false }
await Task { try? await Task.sleep(nanoseconds: 1_000_000_000) }.value
items = .samples()
withAnimation { show = true }
}
func action(index: Int, item: Item) {
print(index, item.code)
}
}
struct Row: View {
let item: Item
let index: Int
var body: some View {
VStack {
HStack(spacing: 16) {
Circle()
.foregroundStyle(icon)
.frame(width: 40)
VStack(alignment: .leading) {
Text(item.code)
.font(.headline)
Text(item.name)
.foregroundStyle(.secondary)
}
Spacer()
Text(item.price)
.font(.headline.monospacedDigit())
}
.foregroundStyle(.background)
.multilineTextAlignment(.leading)
.padding()
}
}
var icon: some ShapeStyle {
let colorss = [[Color]].colors
let colors = colorss[index % colorss.count]
return LinearGradient(colors: colors, startPoint: .top, endPoint: .bottom)
}
}
struct Item: Identifiable, Hashable {
var id: String { code }
let code: String
let name: String
let price: String
init(code: String, name: String) {
self.code = code
self.name = name
self.price = "$\(Int.random(in: 30..<999))"
}
}
extension [Item] {
static func samples() -> Self {
return [
Item(code: "MFST", name: "マイクロソフト"),
Item(code: "AAPL", name: "アップル"),
Item(code: "NVDA", name: "エヌビディア"),
Item(code: "AMZN", name: "アマゾン・ドット・コム"),
Item(code: "META", name: "メタ・プラットフォームズ"),
Item(code: "GOOG", name: "アルファベット"),
Item(code: "BRK", name: "バークシャー・ハサウェイ"),
Item(code: "LLY", name: "イーライリリー"),
Item(code: "AVGO", name: "ブロードコム"),
Item(code: "JPM", name: "JPモルガン・チェース・アンド・カンパニー"),
]
}
}
extension [[Color]] {
static let colors: [[Color]] = [
[.orange, .pink],
[.mint, .green],
[.cyan, .blue],
[.purple, .pink],
[.purple, .orange],
[.cyan, .mint],
[.yellow, .orange],
[.red, .blue],
]
}
#Preview {
ContentView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment