1つの行にList
と2つのボタンがあるとします。行全体を強調表示せずに、どのボタンがタップされたかを区別するにはどうすればよいですか?
このサンプルコードでは、行のいずれかのボタンがタップされると、両方のボタンのアクションコールバックが呼び出されます。
// a simple list with just one row
List {
// both buttons in a HStack so that they appear in a single row
HStack {
Button(action: {
print("button 1 tapped")
}) {
Text("One")
}
Button(action: {
print("button 2 tapped")
}) {
Text("Two")
}
}
}
// when tapping just once on either button:
// "button 1 tapped"
// "button 2 tapped"
BordlessButtonStyle()を使用する必要があります。
List([1, 2, 3], id: \.self) { row in
HStack {
Button(action: {
print("Buton at \(row) with name A")
}) {
Text("Row: \(row)" + " Name: A")
}.buttonStyle(BorderlessButtonStyle())
Button(action: {
print("Buton at \(row) with name B")
}) {
Text("Row: \(row)" + " Name: B")
}.buttonStyle(BorderlessButtonStyle())
}
}
Button
行に含まれる場合、List
に関する特定の問題のようです。
回避策:
List {
HStack {
Text("One").onTapGesture { print("One") }
Text("Two").onTapGesture { print("Two") }
}
}
これにより、目的の出力が得られます。
Group
の代わりにText
を使用して、「ボタン」の洗練されたデザインを作成することもできます。
SwiftUIとの違いの1つは、Macアプリを使用している可能性があるため、UIButtonなどの特定のインスタンスを作成しないことです。 SwiftUIでは、ボタンタイプのものを要求しています。
この場合、リストの行にいるので、システムはフルサイズを提供し、どこかをタップしてアクション、ボタンをトリガーします。 2つ追加したので、どこかをタップすると両方がトリガーされます。
2つの個別のビューを追加して、それらに.onTapGesture
それらを基本的にボタンとして機能させるには、セル行のタップフラッシュや、SwiftUIが提供する機能のような他の自動ボタンを失うことになります。
List {
HStack {
Text("One").onTapGesture {
print("Button 1 tapped")
}
Spacer()
Text("Two").onTapGesture {
print("Button 2 tapped")
}
}
}
独自のButtonStyleを作成する必要があります。
struct MyButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.foregroundColor(.accentColor)
.opacity(configuration.isPressed ? 0.5 : 1.0)
}
}
struct IdentifiableString: Identifiable {
let text: String
var id: String { text }
}
struct Test: View {
var body: some View {
List([
IdentifiableString(text: "Line 1"),
IdentifiableString(text: "Line 2"),
]) {
item in
HStack {
Text("\(item.text)")
Spacer()
Button(action: { print("\(item.text) 1")}) {
Text("Button 1")
}
Button(action: { print("\(item.text) 2")}) {
Text("Button 2")
}
}
}.buttonStyle(MyButtonStyle())
}
}