I have a class CommentView
that has an optional closure (for simplification purposes, I've cut down the code to its bare basics to make it easy for the reader):
struct CommentView: View
{
@State var enterButtonPushed: ((Comment) -> Void)?
init(enterButtonPushed: @escaping (Comment) -> Void)
{
self.enterButtonPushed = enterButtonPushed
}
var body: some View
{
Button("Enter")
{
if let enterButtonPushed = self.enterButtonPushed
{
enterButtonPushed(Comment())
}
else
{
print("EnterButtonPushed is nil")
}
}
.buttonStyle(.borderedProminent)
}
}
A CommentView
class is created correctly from another class:
CommentView
{
comment in self.reader.comments.append(comment)
}
When I push the enter button, the print statement is indicating that the closure is nil, even though I clearly initialized it with a value. What is the correct way syntactically to declare, instantiate and unwrap an optional closure?
The closure is passed from outside the view, so it should not be a @State
. @State
s are things that are "internal" to the view, and this is why it is often said that @State
should always be private
.
Just make it a let
, and since the initialiser doesn't take an optional closure, it doesn't need to be optional, and you don't need to unwrap it.
let enterButtonPushed: (Comment) -> Void
If you would like it to be optional, that's fine too, and the way you are unwrapping it is correct.
As for why enterButtonPushed
is not set, even when you did set it in init
, this is because @State
is a property wrapper. Setting enterButtonPushed
this way is just syntactic sugar for setting the property wrapper's wrappedValue
. And the setter of wrappedValue
can totally just do nothing, because you are using @State
incorrectly.