swift 4.2 Cannot convert value of type '(_) -> Void' to expected argument type '(() -> Void)?'

18.6k Views Asked by At

==> swift 3 version in perfect work but swift 4 and swift 4.2 in now working.

static func animate(_ duration: TimeInterval,
                    animations: (() -> Void)!,
                    delay: TimeInterval = 0,
                    options: UIViewAnimationOptions = [],
                    withComplection completion: (() -> Void)! = {}) {

    UIView.animate(
        withDuration: duration,
        delay: delay,
        options: options,
        animations: {
            animations()
        }, completion: { finished in
            completion()
    })
}

static func animateWithRepeatition(_ duration: TimeInterval,
                                   animations: (() -> Void)!,
                                   delay: TimeInterval = 0,
                                   options: UIViewAnimationOptions = [],
                                   withComplection completion: (() -> Void)! = {}) {

    var optionsWithRepeatition = options
    optionsWithRepeatition.insert([.autoreverse, .repeat])

    self.animate(
        duration,
        animations: {
            animations()
        },
        delay:  delay,
        options: optionsWithRepeatition,
        withComplection: { finished in
            completion()
    })
}

Error display on xcode =>

Cannot convert value of type '(_) -> Void' to expected argument type '(() -> Void)?'

3

There are 3 best solutions below

6
Dávid Pásztor On BEST ANSWER

You declared the animate function such that its completion parameter takes no input arguments. However, you are trying to call an input argument, finished in your closure when you call that function in animateWithRepetition. Just remove finished and your code compiles fine.

static func animateWithRepetition(_ duration: TimeInterval, animations: (() -> Void)!, delay: TimeInterval = 0, options: UIView.AnimationOptions = [], withComplection completion: (() -> Void)! = {}) {

    var optionsWithRepetition = options
    optionsWithRepeatition.insert([.autoreverse, .repeat])

    self.animate(duration, animations: {
        animations()
    }, delay: delay, options: optionsWithRepeatition, withCompletion: {
        completion()
    })
}

P.S.: I've corrected the typos in your input argument names. Passing in an input argument of implicitly unwrapped type also doesn't make much sense. Either make animations a normal Optional and safely unwrap it or rather make it non-Optional if it should never be nil.

0
Nishu_Priya On

In your function declaratation:

static func animate(_ duration: TimeInterval,
                    animations: (() -> Void)!,
                    delay: TimeInterval = 0,
                    options: UIViewAnimationOptions = [],
                    withComplection completion: (() -> Void)! = {})

you have defined completion handler as (() -> Void)!, that is, it does not have any parameter.

But when you call this function:

self.animate(
        duration,
        animations: {
            animations()
        },
        delay:  delay,
        options: optionsWithRepeatition,
        withComplection: { finished in
            completion()
    })

you are giving the parameter finished in completion block. That's why its giving error.

0
Vadim Zhuk On

Under Swift4 compiler assumed () -> Void as (Void) -> Void but since that its matters if there is an argument (even if it's Void)