SwiftUI-在协议中返回不透明类型

SwiftUI-在协议中返回不透明类型,swift,swiftui,Swift,Swiftui,目前,我有一个协议媒体,它的方法是displaySummary()->一些视图。问题是,据我所知,在协议中不能返回不透明类型 protocol Media { func displaySummary() -> some View } 实现代码如下所示: final class Playlist: Media { func displaySummary() -> some View { return HStack { Text("Summary") .pa

目前,我有一个协议
媒体
,它的方法是
displaySummary()->一些视图
。问题是,据我所知,在协议中不能返回不透明类型

protocol Media {
  func displaySummary() -> some View
}
实现代码如下所示:

final class Playlist: Media {
func displaySummary() -> some View {
  return HStack {
    Text("Summary")
      .padding(.all)
      .background(Color.black)
  }
}
let media: Media = Playlist()

var body: some View {
  ScrollView(.horizontal, showsIndicators: false) {
    media.displaySummary()
  }
}
在ContentView中,我有以下内容:

final class Playlist: Media {
func displaySummary() -> some View {
  return HStack {
    Text("Summary")
      .padding(.all)
      .background(Color.black)
  }
}
let media: Media = Playlist()

var body: some View {
  ScrollView(.horizontal, showsIndicators: false) {
    media.displaySummary()
  }
}

有没有办法在SwiftUI中实现这一点?

我能够使用类型擦除来解决它

protocol Media {
 func displaySummary() -> AnyView
}
在任意视图中简单包裹不透明视图:

final class Playlist: Media {
 func displaySummary() -> AnyView {
   return AnyView(HStack {
     Text("Summary")
       .padding(.all)
       .background(Color.black))
     })
   }
 }

这里是使用协议
associatedtype
的变体,实际上是SwiftUI本地方法,如果我们在其自动生成的模块中看到的话。这允许避免类型擦除包装,并直接使用视图

使用Xcode 11.4/iOS 13.4进行测试

protocol Media {
    associatedtype Summary : View
    func displaySummary() -> Self.Summary
}

final class Playlist: Media, Identifiable {
    func displaySummary() -> some View {
        return HStack {
            Text("Summary")
                .padding(.all)
                .background(Color.black)
        }
    }
}

struct PlaylistView: View {
    let playlist = Playlist()

    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            playlist.displaySummary()
        }
    }
}

在这个实现中,您正在实例化一个播放列表对象,而不将其约束到协议,如果您这样做,则会出现错误。也就是说,
let playlist:Media=playlist()