SwiftUI:ViewModifier,其中内容是图像
我收到一个错误“SwiftUI:ViewModifier,其中内容是图像,swift,swiftui,swift-protocols,Swift,Swiftui,Swift Protocols,我收到一个错误“键入'PlayButtonModifier'不符合协议'ViewModifier'”,我不明白为什么,更重要的是,不知道如何正确操作 我只是尝试为图像创建一个视图修改器,这样我就可以在其上使用例如.resizeable(),它只在图像中定义 在ViewModifier协议中,定义了Content的Typealias。我的naiv认为这应该是可行的: struct PlayButtonModifier: ViewModifier { typealias Content =
键入'PlayButtonModifier'不符合协议'ViewModifier'
”,我不明白为什么,更重要的是,不知道如何正确操作
我只是尝试为图像
创建一个视图修改器
,这样我就可以在其上使用例如.resizeable()
,它只在图像
中定义
在ViewModifier
协议中,定义了Content
的Typealias
。我的naiv认为这应该是可行的:
struct PlayButtonModifier: ViewModifier {
typealias Content = Image
func body(content: Content) -> some View {
content
}
}
不,太容易了。结构的隐式类型别名也会发生同样的情况:
struct PlayButtonModifier: ViewModifier {
func body(content: Image) -> some View {
content
}
}
同样的错误
这里怎么了?它的正确性如何?感谢您的评论和讨论,我最终使用了以下代码片段。基本上,它是专门用于图像的
ViewModifier
的实现
protocol ImageModifier {
/// `Body` is derived from `View`
associatedtype Body : View
/// Modify an image by applying any modifications into `some View`
func body(image: Image) -> Self.Body
}
extension Image {
func modifier<M>(_ modifier: M) -> some View where M: ImageModifier {
modifier.body(image: self)
}
}
我不是100%满意,因为必须定义修饰符以返回某些视图
或返回图像
。这两种情况都有缺点,不能与SwiftUI完美集成
当定义
ImageModifier
以返回图像时,它减少了仅将图像修改为特定于图像的修改器的可能性(实际上可调整大小()当定义它返回some View
时,我不能链接ImageModifier
s,因为第二个修饰符必须是ViewModifier
在这种情况下,如果修改特定于特定的视图类型,Image
也就是说,您可以直接在该视图类型上添加扩展:
extension Image {
func myImageModifier() -> some View {
self
.resizable()
.aspectRatio(1.0, contentMode: .fit)
.clipShape(Circle())
}
}
下面是一个完整的操场文本示例。如果你在游乐场“资源”文件夹“otter.png”中添加一张可爱的水獭图片,你会得到一个更漂亮的结果:)
这里的内容是不透明的typealias。。。这将帮助你澄清这个领域。嗨@Asperi,你链接背后的答案很好地解释了幕后发生的事情。谢谢你。现在有一个100万美元的问题:我如何使用它?苹果付出了所有的努力,甚至包括对Swift的语法修改,只是为了能够修改标准的普通视图?甚至连图片和文字都没有?我仍然相信,其中有一些东西,我只是还没有发现。所有修饰符实际上都是一个函数,即..resizeable()。ViewModifier是通用视图修改的通用机制。对于特定的修改,您可以创建特定的功能、可计算属性、专用视图等。唯一的一个要求是——这些应该生成一些视图作为输出。
extension Image {
func myImageModifier() -> some View {
self
.resizable()
.aspectRatio(1.0, contentMode: .fit)
.clipShape(Circle())
}
}
import PlaygroundSupport
import SwiftUI
let image = (UIImage(named: "Otter.png") ?? UIImage(systemName: "exclamationmark.square")!)
struct ContentView: View {
var body: some View {
VStack {
Text("hello world")
Image(uiImage: image)
.myImageModifier()
}
}
}
extension Image {
func myImageModifier() -> some View {
self
.resizable()
.aspectRatio(1.0, contentMode: .fit)
.clipShape(Circle())
}
}
PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView())