Casting issues regarding optionals

I am converting an older application from Objective-C to Swift. In the objective c code their is a line that type casts a UIView to a UIButton. Here it is..

if ([((UIButton *)[self.view viewWithTag:1030]) isSelected]) {
     //do something
}


Now when converting it to Swift I did this...

if ((self.view.viewWithTag(1025) as? UIButton).selected == true) {
     //do something
}


Now I get no errors. But when I run the application in Swift I get a fatal error saying it unwrapped a nil value. This is happening because you cannot typecast a view as a UIButton becuase it is not the subclass view. But in Objective-c the cast works. So now how do I convert a view to a button in Swift? Thanks in advance.

Sorry the tag number in the swift code should be 1030.

You didn't have to fix the tag number; that's an implementation detail that doesn't matter to anyone but you. Thanks all the same. 🙂


UIView's viewWithTag() function returns an optional value, meaning it can be nil. The reason your code worked in Objective-C is that it allowed nil just fine—anything called on nil just returns nil. So if the button is nil, calling -isSelected on it returns nil instead of NO. The if statement treats both of them the same way, so the if statement ends up working as you expect. The downside of this is the ambiguity: it's not immediately obvious that you might end up with nil, which could lead to a bug in other use cases. Swift doesn't allow this kind of implicit nil for the sake of total clarity and safety.

So, all you need to do is acknowledge that nil is okay here using optional chaining. Like this:

if (view.viewWithTag(1030) as? UIButton)?.selected = true {
     //do something
}


By the way, in Swift you don't need the explicit self. most of the time, and you can skip the outermost set of parentheses.

Try the code like this:


if let button = self.view.viewWithTag(1025) as? UIButton where button.selected == true { 
     //do something 
}


In your original code, the result of your cast was an optional (because you used 'as?'), but you never unwrapped the optional.

Thank you for your help. Appreciate it.

Casting issues regarding optionals
 
 
Q