The callAsFunction method is a special method that allows you to call an instance of a type as if it were a function. For example, you can define a struct with a callAsFunction method that takes some arguments and returns a value:
struct Adder {
var base: Int
func callAsFunction(_ x: Int) -> Int {
return x + base
}
}
let add3 = Adder(base: 3)
let result = add3(10) // result is 13
This is equivalent to calling the callAsFunction method explicitly:
let result = add3.callAsFunction(10) // result is 13
You can use callAsFunction to implement custom operators in Swift. For example, you can create a struct that represents a matrix and define a callAsFunction method that performs matrix multiplication:
struct Matrix {
var elements: [[Double]]
func callAsFunction(_ other: Matrix) -> Matrix {
// Perform matrix multiplication and return the result
}
}
let A = Matrix(elements: [[1, 2], [3, 4]])
let B = Matrix(elements: [[5, 6], [7, 8]])
let C = A(B) // C is the matrix product of A and B
The callAsFunction method can be useful for creating callable objects that encapsulate some logic or state. For example, you can use it to create a custom view modifier in SwiftUI that takes a closure as an argument:
struct OnTap: ViewModifier {
var action: () -> Void
func body(content: Content) -> some View {
content.onTapGesture(perform: action)
}
func callAsFunction(_ action: @escaping () -> Void) -> OnTap {
OnTap(action: action)
}
}
let onTap = OnTap()
Text("Hello")
.modifier(onTap {
print("Tapped")
})
This is equivalent to calling the modifier method with an instance of OnTap:
Text("Hello")
.modifier(OnTap {
print("Tapped")
})
One common SwiftUI environment value that uses callAsFunction is DismissAction. This is a structure that you can use to dismiss a view that is presented modally, such as a sheet or a full screen cover.
@Environment(\.dismiss) private var dismiss
Then you can call the dismiss value as a function to dismiss the view:
Button("Done") {
dismiss() // Implicitly calls dismiss.callAsFunction()
}
This is equivalent to calling the callAsFunction method explicitly:
Button("Done") {
dismiss.callAsFunction()
}
Another common SwiftUI environment value that uses callAsFunction is OpenURLAction. This is a structure that you can use to open a URL, following system conventions.
@Environment(\.openURL) private var openURL
Then you can call the openURL value as a function with a URL argument to open it:
Button("Visit Website") {
if let url = URL(string: "https://www.apple.com") {
openURL(url) // Implicitly calls openURL.callAsFunction(url)
}
}
This is equivalent to calling the callAsFunction method explicitly:
Button("Visit Website") {
if let url = URL(string: "https://www.apple.com") {
openURL.callAsFunction(url)
}
}
These are some examples of how SwiftUI uses callAsFunction to simplify the syntax for calling environment values as actions.