我需要根據 @State 布林值顯示兩個不同的影像,以便當用戶按下影像時它會顯示第二個影像,而當用戶釋放它時它會回傳顯示第一個影像。這一切都很完美,但是我有一種情況,我需要在 ForEach 回圈中做同樣的事情,因為我不相信 Swift 可以處理動態變數,所以我不知道如何做到這一點。
在下面的代碼中,您將看到如何配置按鈕的結構,然后在 MainView 的 ForEach 回圈中呼叫它。btnHover 變數需要在每次迭代時更改,否則所有按鈕都會在按下單個按鈕時顯示懸停影像。
此外,我不能將它放入一個單獨的結構中,然后在主視圖中呼叫它。今天我花了很多時間走這條路,似乎如果你從一個單獨的結構呼叫 NavigationLink,你就不能再彈出到根目錄。我不明白,但這顯然是交易。所以,我需要在主視圖中進行這項作業,而不是在單獨的結構中。
真正的代碼要復雜得多(即每個按鈕實際上都是一個 NavigationLink),但我盡量將示例簡單化。
struct PressActions: ViewModifier {
var onPress: () -> Void
var onRelease: () -> Void
func body(content: Content) -> some View {
content
.simultaneousGesture(
DragGesture(minimumDistance: 0)
.onChanged({ _ in
onPress()
})
.onEnded({ _ in
onRelease()
})
)
}
}
extension View {
func pressAction(onPress: @escaping (() -> Void), onRelease: @escaping (() -> Void)) -> some View {
modifier(PressActions(onPress: {
onPress()
}, onRelease: {
onRelease()
}))
}
}
struct DynamicBtn: View {
var btnName: Bool
var body: some View {
Image(btnName == true ? "DynamicHover" : "Dynamic")
.resizable()
.aspectRatio(contentMode: .fit)
}
}
struct MainView: View {
@State private var btnHover: Bool = false
let user = [Tim, John, Joe, Mary]
var body: some View {
ForEach(user, id: \.self) { user in
VStack {
DynamicBtn(btnName: btnHover)
.pressAction {
btnHover = true
} onRelease: {
btnHover = false
}
}
}
}
}
uj5u.com熱心網友回復:
嘗試類似這種方法,以便能夠“按下”您
DynamicBtn并顯示特定影像,然后釋放“按下”以顯示原始影像:
struct MainView: View {
let users = [User(name: "Tim"), User(name: "John"), User(name: "Joe"), User(name: "Mary")]
@State var selectedUser: User? // <-- here
var body: some View {
ForEach(users, id: \.self) { user in
DynamicBtn(btnName: selectedUser == user) // <-- here
.pressAction {
selectedUser = user // <-- here
} onRelease: {
selectedUser = nil // <-- here
}
}
}
}
// for testing
struct User: Identifiable, Hashable {
let id = UUID()
var name = ""
}
注意:您可以只使用Image(btnName ? "DynamicHover" : "Dynamic")in DynamicBtn。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/487479.html
