3

==> 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)?'

nick
  • 1,090
  • 1
  • 11
  • 24
Digvijaysinh Gida
  • 381
  • 1
  • 7
  • 20
  • Which line? Remove ` finished in` in that line, because `withComplection` doesn't have a param, there is no "finished". – Larme Jan 29 '19 at 11:40
  • Off-topic but can someone explain what the ! means in the argument declaration `animations: (() -> Void)!` – Joakim Danielson Jan 29 '19 at 11:44
  • @JoakimDanielson look up implicitly-unwrapped optionals – Dávid Pásztor Jan 29 '19 at 11:45
  • @DávidPásztor Thanks, I did and I understand the concept, when using it for an `@IBOutlet` for instance, but I don't really understand what it means to have them in an argument declaration. – Joakim Danielson Jan 29 '19 at 11:54
  • 1
    @JoakimDanielson implicitly unwrapped optionals (IUO) always have the same meaning. They are optional values, but whenever they are accessed, they will be force unwrapped to provide a non-optional value (actually this changed a bit in Swift 4.2, now they are only force-unwrapped when a non-optional value is needed, otherwise they aren't unwrapped). If you declare a function input argument as IUO, it will be force unwrapped inside the function whenever used, but you can still pass in an optional. Whether this has a real use case or not is a different question (for which I'd say no). – Dávid Pásztor Jan 29 '19 at 12:02

3 Answers3

2

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.

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • I'm remove `finished` here show me error Cannot convert value of type '() -> Void' to expected argument type '((Bool) -> Void)?' – Digvijaysinh Gida Jan 29 '19 at 12:01
  • @Digvijay that piece of code compiles just fine for me when declaring both of your function in an extension to `UIView`. Where did you define them? – Dávid Pásztor Jan 29 '19 at 12:03
  • https://github.com/IvanVorobei/SegmentedControl I'm use this lib into my project and i'm fetch this issue. @DávidPásztor – Digvijaysinh Gida Jan 29 '19 at 12:06
  • bro i'm use this lib class and that class in show me this error. – Digvijaysinh Gida Jan 29 '19 at 12:14
  • @Digvijay so the 2 functions in your question aren't declared in your code, but in the linked library? if that's the case, you should open a GitHub issue for the library and get them to fix their code. If these functions are declared in your code, then you need to update your question with where they are declared. As I've stated, declaring them as an extension to `UIView` works just fine – Dávid Pásztor Jan 29 '19 at 12:22
  • The implicitly unwrapped optional is there probably to avoid `@escaping`. – Sulthan Jan 29 '19 at 12:23
0

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.

Nishu_Priya
  • 1,251
  • 1
  • 10
  • 23
0

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

Vadim Zhuk
  • 334
  • 2
  • 10