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?
This can happen when the file is not a member of the Target. Open the file where autocomplete is not working and show the the "Utilities" tab in the top right of Xcode (blue in the screenshot below). Ensure your Target (typically your app's name) is checked.
Show/hide completions: ⎋ ( Escape ) OR ⌃Space ( Control + Space ) Type some code, use either ⎋ or ⌃Space to toggle auto-complete (I'm hooked on Escape ), and Xcode will offer a few intelligent suggestions to complete your code.
Xcode configures the initial build phases for each target at creation time, but you can add or modify those build phases later. You might add build phases to copy additional files to your app bundle, or to execute custom shell scripts. You can also examine the build phases to diagnose potential issues.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With