Created
July 28, 2024 06:04
-
-
Save Koshimizu-Takehito/e8e4ad74c04c584bea5f7d1092e26dfe to your computer and use it in GitHub Desktop.
Buttonがセルになるサンプル
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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