为什么resizeable()必须是View中的第一个方法?

nip*_*ese 0 xcode swiftui

在这里使用XCode11 beta 4:

为什么.resizable()要首先列出该方法以免使Canvas崩溃?

例如:

作品

struct CircleImage: View {
    var body: some View {
        Image("Pizza")
            .resizable()
            .scaledToFit()
            .clipShape(Circle())
            .overlay(
                Circle()
                    .stroke(Color.gray, lineWidth: 4)
            )
        .shadow(radius: 10)
    }

}
Run Code Online (Sandbox Code Playgroud)

不起作用

struct CircleImage: View {
    var body: some View {
        Image("Pizza")            
            .scaledToFit()
            .resizable()
            .clipShape(Circle())
            .overlay(
                Circle()
                    .stroke(Color.gray, lineWidth: 4)
            )
        .shadow(radius: 10)
    }

}
Run Code Online (Sandbox Code Playgroud)

该错误似乎具有误导性:

Value of type 'some View' has no member 'resizable'

kon*_*iki 6

我同意,很多时候SwiftUI中的编译错误都是极具误导性的。但是在这种情况下,事实并非如此。

看的声明resizable()scaledToFit()

extension View {
    @inlinable public func scaledToFit() -> some View
}
Run Code Online (Sandbox Code Playgroud)
extension Image {
    public func resizable(capInsets: EdgeInsets = EdgeInsets(), resizingMode: Image.ResizingMode = .stretch) -> Image
}
Run Code Online (Sandbox Code Playgroud)

scaledToFit()是View的扩展。这意味着您可以使用它来修改任何视图。虽然resizable()是Image的扩展,所以您只能在Image上使用它。

并且由于scaledToFit()返回some View,从技术上讲,它不再是Image。这意味着您无法调用.resizable()它。

同样的事情发生与.font().fontWeight()。它们只能应用于Text,然后它们还返回Text。这意味着这些组合是有效的:

Text("hello").font(.title).fontWeight(.bold).frame(width: 300)
Text("hello").fontWeight(.bold).font(.title).frame(width: 300)
Run Code Online (Sandbox Code Playgroud)

但是这些不是:

Text("hello").font(.title).frame(width: 300).fontWeight(.bold)
Text("hello").frame(width: 300).fontWeight(.bold).font(.title)
Text("hello").fontWeight(.bold).frame(width: 300).font(.title)
Run Code Online (Sandbox Code Playgroud)

由于.frame()return some View,您不能再使用Text特定的修饰符。

现在,再次查看您的错误消息:Value of type 'some View' has no member 'resizable'。就是说some View不知道resizable,那是真的,只有Image事实。

beta4中的声明已被清理。修改视图后some View,它们通常返回一些很长的类型,而不是返回,例如:Self.Modified<_FrameLayout>Self.Modified<_AspectRatioLayout>