David Cittadini
David Cittadini

Reputation: 379

Casting a UIBarButtonItem to a UIButton

If I want to cast UIToolbar items to a UIBarButtonItem, XCode makes me write it this way:

    for item in toolBar!.items as! [UIBarButtonItem]! {
        // Do something
    }

However, once it does this it then says

"Forced cast from '[UIBarButtonItem]?' to '[UIBarButtonItem]' only unwraps optionals; did you mean to use '!'?"

So, how do I write the above cast to a UIBarButtonItem without XCode showing any errors/warnings?

Upvotes: 0

Views: 1290

Answers (5)

André Slotta
André Slotta

Reputation: 14030

An easy way around it without any if / guard letting or force unwrapping is to use forEach instead:

toolbar.items?.forEach { item in
    // do whatever you want
}

Upvotes: 1

vadian
vadian

Reputation: 285069

Look at the declaration of items

var items: [UIBarButtonItem]? { get set }

It's an optional array of UIBarButtonItem, there is no need to cast anything. That's what the warning says.

Just check safely if there are items, UIButton is not involved at all.

if let bar = toolBar, let items = bar.items {
   for item in items {
      // Do something
   }
}

However if the toolbar and its items are designed in Interface Builder and won't be changed at runtime you can force unwrap both.

   for item in toolBar!.items! {
      // Do something
   }

Upvotes: 1

Matic Oblak
Matic Oblak

Reputation: 16774

What your warning says is that you are not changing a class (typecasting) but only force-unwrapping. In your case toolBar!.items is a type of [UIBarButtonItem]? and you are converting it to [UIBarButtonItem] which can simply be done by saying toolBar!.items!.

But this has nothing to do with UIButton you mentioned in your title. And you may NOT typecast UIBarButtonItem to UIButton. There is a big difference between the two as UIBarButtonItem is actually instructions to create a button and not a button itself. If you really need to get that button you will need to add it as a custom view using UIBarButtonItem(customView: ) and then extract it as item.customView as? UIButton.

Upvotes: 0

Mohammadalijf
Mohammadalijf

Reputation: 1377

you can check if there are items then do a foreach.

// check if toolBar have any items
guard let items = toolBar.items else { return }
// then do a loop with items
for item in items {
    // do something
}

also you can use ?? to provide default value

// provide an empty array if items where nil
for item in toolBar.items ?? [] {
    // do something
}

Upvotes: 0

Mahendra
Mahendra

Reputation: 8904

You can use if let for safe type casting.

    if let items = toolBar.items {

        for item in items {
            if let btn = item as? UIButton {
                print("'btn' is UIButton.")
            } else {
               print("It is not UIButton.")
            }
        }
    }

Upvotes: 1

Related Questions