使用 SwiftUI List()、ForEach()、.onTapGesture WatchOS6 传递值的问题
Posted
技术标签:
【中文标题】使用 SwiftUI List()、ForEach()、.onTapGesture WatchOS6 传递值的问题【英文标题】:Problem passing value with SwiftUI List(), ForEach(), .onTapGesture WatchOS6 【发布时间】:2019-12-19 14:11:01 【问题描述】:我正在尝试使用 .onTapGesture() 调用被点击视图上的方法并传递某种 ID 或任何其他形式的标识符,但我不知道如何。
我有一个视图 ListView
,它是根据从数组 trackPreviewList: [TrackpreviewList]
获取的数据创建的。
视图如下所示:
struct ListView: View
@ObservedObject var model: PlaybackService
@State var list = PlaybackService.sharedInstance.trackPreviewList
var body: some View
List
Section(header: Text("Songs"))
ForEach(model.trackPreviewList!, id: \.id)
Text($0.artistName + ": " + $0.name)
.onDelete(perform: deleteTrack)
.onTapGesture(perform: skipTo)
我对 SwiftUI 和一般编码非常陌生,但我认为正确的方法是说单元格(视图?) 2 已被点击,因此将 2 传递给方法func playerSkipTo(skipToIndex: Int)
我尝试将值 2 硬编码为这适用于硬编码值:
虽然我对如何传递某种标识符一无所知,但我认为我的问题是我试图访问该方法“知道它”的范围之外的对象。
我试图使用 $0.name 变量来查看是否可以传递任何内容,但我收到此错误Contextual closure type '() -> Void' expects 0 arguments, but 1 was used in closure body
我认为这是因为 .onTapGesture() 方法没有闭包?。
我尝试使用与使用 IndexSet 的 .onDelete() 方法相同的逻辑,如下所示:
最后我想将值传递给的方法如下所示:
func playerSkipTo(skipToIndex: Int)
if skipToIndex < ((trackPreviewList!.underestimatedCount)-1)
_ = firstly
TracklistProvider.sharedInstance.getPlaybackURL(trackPreview: trackPreviewList![skipToIndex])
.map playbackoptions in
self.createPlayerItemFromLink(assetURL: (playbackoptions?.playbackUrl)!)
.done
self.replacePlayerItem()
else
print("The index \(skipToIndex) is out of bounds")
我知道我将需要更改 playerSkipTo()
方法以接收 IndexSet,我也尝试过尝试将其转换为 Int 等。
非常感谢任何帮助或指点!
Heres the playerSkipTo method:
if skipToIndex < ((trackPreviewList!.underestimatedCount)-1)
_ = firstly
TracklistProvider.sharedInstance.getPlaybackURL(trackPreview: trackPreviewList![skipToIndex])
.map playbackoptions in
self.createPlayerItemFromLink(assetURL: (playbackoptions?.playbackUrl)!)
.done
self.replacePlayerItem()
else
print("The index \(skipToIndex) is out of bounds")
【问题讨论】:
【参考方案1】:不是跳到索引,而是跳到特定的轨道对象:
func playerSkipTo(_ playbackoptions: PlaybackOptions)
// ...
然后更改您的视图代码以在 Text
而不是 ForEach
上调用此函数:
List
Section(header: Text("Songs"))
ForEach(model.trackPreviewList!, id: \.id)
Text($0.artistName + ": " + $0.name)
.onTapGesture
self.playerSkipTo($0)
【讨论】:
嘿@Yonat,感谢您的回答。我尝试了你告诉我的,但这让我回到了我之前遇到的另一个错误。Type '_' has no member 'id'
TrackPreviews 不符合 Identifiable,所以我必须指定如何使用 id
参数来识别它们。此外,TrackPreviews 是我在以前的实习中使用的 API 客户端的一部分,因此我无法更改或将协议添加到模型中。我尝试制作模型的副本并使用它,但这需要我跟踪两个数组,因为我需要一个用于显示,一个用于对后端的请求
当我尝试输入硬编码值时,我得到这个错误:Value of type 'ListView' has no member 'playerSkipTo'
TrackPreview
有哪些成员?您可以使用其中之一来识别轨道吗?例如:var id: String self.url.absoluteString
至于缺少playerSkipTo
:先添加那个函数,然后调用即可。
TrackPreview
有 public let id: Int
。 playerSkipTo
method 在我的 PlaybackService
中,我会将其添加到我的问题的底部,以便您查看。再次感谢您的宝贵时间,我真的被困住了。【参考方案2】:
您可以使用 ZStack 顶部的按钮:
List
ForEach(appData.assets) asset in
ZStack
HStack
VStack(alignment: .leading)
Text(asset.value)
.font(.headline)
Spacer()
Button(action: assetPressed(id: asset.id), label:
Text("")
)
.onDelete(perform: deleteAsset)
【讨论】:
以上是关于使用 SwiftUI List()、ForEach()、.onTapGesture WatchOS6 传递值的问题的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI 使用 List 和 Foreach 遍历字典中的键并创建列表视图
使用 SwiftUI List()、ForEach()、.onTapGesture WatchOS6 传递值的问题
SwiftUI 的 List/ForEach 视图中是不是可以有一个 Button(action: -)
带有 Xcode 11 beta 7 的 SwiftUI 未更新 List / ForEach 的内容
SwiftUI:当 List 和 ForEach 嵌入 TabView 时 WatchOS 8.1 中的 NavigationView 错误