In SwiftUI, what's the difference between .modifier and .layout

Viewed 777

I cannot seem to find any difference between applying a ViewModifier using either .modifier or .layout. They both produce the same result. Anyone knows what's the difference between these two. There's no documentation whatsoever.

For example, given this modifier:

struct RedTitle: ViewModifier {
    func body(content: Content) -> some View {
        return content.foregroundColor(.red).font(.title)
    }
}

These two views turn out to look identical:

Text("Hello world!").layout(RedTitle())
Text("Hello world!").modifier(RedTitle())
1 Answers

UPDATE

As of Xcode 11 beta 4, the layout modifier has been marked deprecated:

extension View {
  @available(*, deprecated, renamed: "modifier")
  @inlinable public func layout<T>(_ layout: T) -> some SwiftUI.View where T : SwiftUI.ViewModifier {
        return modifier(layout)
    }
}

ORIGINAL

There is no difference as of Xcode 11 beta 2. That doesn't mean there will always be no difference. Possibly layout is left over from an older design and needs to be removed, or perhaps a later beta will make it behave differently.

The complete interface exported by SwiftUI can be found in this file:

/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/SwiftUI.framework/Modules/SwiftUI.swiftmodule/arm64.swiftinterface

Looking in that file, you can find the declaration of func modifier:

extension View {
  public typealias Modified<T> = _ModifiedContent<Self, T> where T : SwiftUI.ViewModifier
  @inlinable public func modifier<T>(_ modifier: T) -> Modified<T> where T : SwiftUI.ViewModifier {
        return .init(content: self, modifier: modifier)
    }
}

And the declaration of func layout:

extension View {
  @inlinable public func layout<T>(_ layout: T) -> Modified<T> where T : SwiftUI.ViewModifier {
        return modifier(layout)
    }
}

Because both modifier and layout are declared @inlinable, Swift includes the function bodies in the .swiftinterface file. We can see that layout just calls modifier and does nothing else.

Related