简体   繁体   中英

iOS Xcode Swift autocomplete broken?

I haven't used Swift that much but coming from Objective C, there's a few things about Swift that's a PITA to get my head around.

In iOS programming, we have animateWithDuration: method, which is part of UIView.

So I tried to use Xcode's autocomplete and begin to type:

UIView.animateWith

The autocomplete shows:

UIView.animateWithDuration(duration: NSTimeInterval, animations: () -> Void)

I then tabbed across to the "duration" field, and then typed in a number:

UIView.animateWithDuration(0.5, animations: () -> Void)

Then I tabbed across again to the animation block, and pressed enter like how I normally do it in Objective C, Xcode now shows:

UIView.animateWithDuration(0.5, animations: { () -> Void in
    code
})

So then I tabbed one last time to replace "code" with my code:

UIView.animateWithDuration(0.5, animations: { () -> Void in
    self.customView?.transform = CGAffineTransformMakeTranslation(0.0, 0.0);
})

That's when Xcode then gives me the error:

Cannot invoke 'animateWithDuration' with an argument list of type '(FloatLiteralConvertible, animations: () -> Void)'

I don't understand. That's the autocomplete code that Xcode generated for me, why is it giving me an error ?

I noticed if do a simple statement like:

UIView.animateWithDuration(0.5, animations: { () -> Void in
    var num = 1 + 1;
})

It doesn't give me any errors.

Any ideas anyone?

From "Calling Methods Through Optional Chaining" :

Any attempt to set a property through optional chaining returns a value of type Void? , which enables you to compare against nil to see if the property was set successfully ...

Therefore the type of the expression

self.customView?.transform = CGAffineTransformMakeTranslation(0.0, 0.0)

is Void? (optional Void). And if a closure consists only of a single expression , then this expression is automatically taken as the return value . The error message is quite misleading, but it comes from the fact that Void? is different from Void .

Adding an explicit return statement solves the problem:

UIView.animateWithDuration(0.5, animations: { () -> Void in
    self.customView?.transform = CGAffineTransformMakeTranslation(0.0, 0.0)
    return
})

Update: Adding an explicit return statement it not necessary anymore with Swift 1.2 (Xcode 6.3). From the beta release notes:

Unannotated single-expression closures with non-Void return types can now be used in Void contexts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM