153

I am trying to delete a row from my Data Source and the following line of code:

if let tv = tableView {

causes the following error:

Initializer for conditional binding must have Optional type, not UITableView

Here is the full code:

// Override to support editing the table view.
func tableView(tableView: UITableView, commitEditingStyle editingStyle:UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {

        // Delete the row from the data source

    if let tv = tableView {

            myData.removeAtIndex(indexPath.row)

            tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

How should I correct the following?

 if let tv = tableView {
Jonathan Soifer
  • 2,715
  • 6
  • 27
  • 50
Del Hinds
  • 2,887
  • 4
  • 12
  • 12
  • 12
    since `tableView` is not an optional value, there is no need to check whether it is nil or not. So you can directly use it, I mean remove that `if let` and just use `tableView` in the function – Eric Qian Jun 24 '15 at 23:39
  • For posterity, after I fixed this issue, I ran into `variable with getter/setter cannot have an initial value`, which was resolved by simply removing the leftover { } block after the initialization, ala this answer: http://stackoverflow.com/a/36002958/4544328 – Jake T. Apr 13 '17 at 18:26

8 Answers8

257

if let/if var optional binding only works when the result of the right side of the expression is an optional. If the result of the right side is not an optional, you can not use this optional binding. The point of this optional binding is to check for nil and only use the variable if it's non-nil.

In your case, the tableView parameter is declared as the non-optional type UITableView. It is guaranteed to never be nil. So optional binding here is unnecessary.

func tableView(tableView: UITableView, commitEditingStyle editingStyle:UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        // Delete the row from the data source
        myData.removeAtIndex(indexPath.row)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

All we have to do is get rid of the if let and change any occurrences of tv within it to just tableView.

nhgrif
  • 61,578
  • 25
  • 134
  • 173
24

for my specific problem I had to replace

if let count = 1
    {
        // do something ...
    }

With

let count = 1
if(count > 0)
    {
        // do something ...
    }
Jacksonkr
  • 31,583
  • 39
  • 180
  • 284
21

In a case where you are using a custom cell type, say ArticleCell, you might get an error that says :

    Initializer for conditional binding must have Optional type, not 'ArticleCell'

You will get this error if your line of code looks something like this:

    if let cell = tableView.dequeReusableCell(withIdentifier: "ArticleCell",for indexPath: indexPath) as! ArticleCell 

You can fix this error by doing the following :

    if let cell = tableView.dequeReusableCell(withIdentifier: "ArticleCell",for indexPath: indexPath) as ArticleCell?

If you check the above, you will see that the latter is using optional casting for a cell of type ArticleCell.

Lehlohonolo_Isaac
  • 1,426
  • 13
  • 15
12

Same applies for guard statements. The same error message lead me to this post and answer (thanks @nhgrif).

The code: Print the last name of the person only if the middle name is less than four characters.

func greetByMiddleName(name: (first: String, middle: String?, last: String?)) {
    guard let Name = name.last where name.middle?.characters.count < 4 else {
        print("Hi there)")
        return
    }
    print("Hey \(Name)!")
}

Until I declared last as an optional parameter I was seeing the same error.

rassar
  • 5,412
  • 3
  • 25
  • 41
Paul Tader
  • 131
  • 1
  • 4
5

condition binding must have optinal type which mean that you can only bind optional values in if let statement

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete {

        // Delete the row from the data source

        if let tv = tableView as UITableView? {


        }
    }
}

This will work fine but make sure when you use if let it must have optinal type "?"

Viral Shah
  • 51
  • 1
  • 2
2

Well, it'd still be convenient (syntactically) if we could declare usual values inside the if's condition. So, here's a trick: you can make the compiler think there is an assignment of Optional.some(T) to a value like so:

    if let i = "abc".firstIndex(of: "a"),
        let i_int = .some(i.utf16Offset(in: "abc")),
        i_int < 1 {
        // Code
    }
0

What it is telling you is - the 2nd guard let or the if let check is not happening on an Optional Int or Optional String. You already have a non-optional value, so guarding or if-letting is not needed anymore

Naishta
  • 11,885
  • 4
  • 72
  • 54
-1

if you check for textfield make sure optional text?

  guard let msg = message.text?.trimmed,!messaged.isEmpty,messaged.count >= 14 else {
            MyVariables.status.image = UIImage(named: "wrong")
            MyVariables.status.message = "Enter Your Message".localized
            MyVariables.status.showInKeyWindow()
            return
        }
  • if let dishes = allDishes.categories{ ScrollView(.horizontal, showsIndicators: false) { LazyHStack { ForEach(dishes) { dish in CategoryView(dish: dish) } } }.frame(height: 128) } same error I got – Shital Jun 05 '23 at 10:02