我将尝试通过示例来说明我要寻找的内容。
比方说,我实现了一个加载图像的概念,看起来像这样:
struct AsyncImage: View {
@ObservedObject private var imageDownloader: ImageDownloader
init(url: URL) {
imageDownloader = ImageDownloader(url: url)
}
var body: Image {
Image(uiImage: imageDownloader.image)
}
}
class ImageDownloader: ObservableObject {
@Published var image: UIImage
init(url: URL) { /* ... */ }
// implementation details unimportant
}
以上实现允许通过应用轻松重用:
struct UserDetailsView: View {
var body: some View {
VStack {
AsyncImage(url: userProfileUrl).resizable().aspectRatio(16.0 / 9.0, contentMode: .fit)
Text(user.name)
}
}
}
但是上述代码无法编译,因为resizable()
只是Image
的一部分。如何以一种干净的方式使此功能可用?
在结构中添加isResizable
标志可以解决该问题,但是该解决方案既不可扩展,也不向前兼容。
使用Publisher
和ViewModifier
可能有效,但是我无法将这些概念结合起来。
有任何解决此问题的建议吗?还是我试图以错误的方式解决这个问题?
答案 0 :(得分:1)
方法可能如下-将所需的修饰符代理到内部包装的dat <- structure(list(Candidates = structure(c(6L, 5L, 7L, 4L, 3L, 2L,
1L), .Label = c("Andrew W.", "Anthony E.", "Hanna F.", "Ignacio R.",
"John R.", "Liza S.", "Peter F."), class = "factor"), Municipality = structure(c(1L,
1L, 1L, 2L, 2L, 2L, 2L), .Label = c("A", "B"), class = "factor"),
Votes = c(100, 120, 140, 110, 335, 225, 400)), class = "data.frame", row.names = c(NA,
-7L))
中。不理想,但在某些情况下值得考虑
Image
因此struct AsyncImage: View {
@ObservedObject private var imageDownloader: ImageDownloader
private let resizing: Bool
init(url: URL, resizalbe: Bool = false) {
imageDownloader = ImageDownloader(url: url)
resizing = resizalbe
}
var body: some View {
var image = Image(uiImage: imageDownloader.image)
if resizing {
image = image.resizable()
}
return image
}
func resizable() -> Self {
AsyncImage(url: imageDownloader.url, resizalbe: true)
}
}
可以编译。
答案 1 :(得分:1)
我最终得到的解决方案是删除整个AsyncImage
概念。毕竟,ImageDownloader
可能会使用某些共享的全局状态(例如某个地方的经理),因此将其隐藏在AsyncImage
中并不是一个好选择。比隐式更好的显式:)
相反,我将下载程序上移了一个级别:
struct UserDetailsView: View {
@ObservedObject var imageDownloader: ImageDownloader
var body: some View {
VStack {
Image(uiImage: imageDownloader.image).resizable().aspectRatio(16.0 / 9.0, contentMode: .fit)
Text(user.name)
}
}
}
此方法具有多个优点:
Image
修饰符AsyncImage
而不是重用ImageDownloader
我的看法:尝试通过混合业务代码和表示代码来使可重用组件不是一个好方法。胜利的单一责任原则:)