maral
maral

Reputation: 269

UIView.animate not work correctly in swift

I Have a function that animates a view's y position. I call this function in tow ways, first as an action target for a button, second by observing a notification. In the first case it works, but in second case when it is called by notification it doesn't animate. the function code is:

func showResult() {
    resultMode = true

    self.containerView.frame.origin.y = CGFloat(1000)
    self.view.layoutIfNeeded()
    UIView.animate(
        withDuration: 3,
        animations: {
            self.containerView.frame.origin.y = CGFloat(200)
            self.view.layoutIfNeeded()
    } ,
        completion: nil
    )
}

it is called:

NotificationCenter.default.addObserver(self, selector: #selector(self.showResult), name: NSNotification.Name(rawValue: "SHOWRESULT"), object: nil)

and

resultBtn.addTarget(self, action: #selector(self.showResult), for: .touchUpInside)

Upvotes: 4

Views: 5830

Answers (3)

Pratheesh Bennet
Pratheesh Bennet

Reputation: 171

In my case I had a closure on button tap on which when tapped needed to animate color. Afters hours of frustration calling the animation inside DispatchMain worked the trick

copyButton.buttonPressedAction = { [weak self] in
  guard let self = self else {
    return
  }
  DispatchQueue.main.async {
    self.backgroundColor = .green
    UIView.animate(withDuration: 2, animations: {() -> Void in
      self.layer.backgroundColor = UIColor.clear.cgColor
    })
  }
}

Upvotes: 3

Sandeep Bhandari
Sandeep Bhandari

Reputation: 20379

Try triggering notification on main thread

    DispatchQueue.main.async {
        NotificationCenter.default.addObserver(self, selector: #selector(self.showResult), name: NSNotification.Name(rawValue: "SHOWRESULT"), object: nil)
    }

Reason:

Regular notification centers deliver notifications on the thread in which the notification was posted. Distributed notification centers deliver notifications on the main thread. At times, you may require notifications to be delivered on a particular thread that is determined by you instead of the notification center. For example, if an object running in a background thread is listening for notifications from the user interface, such as a window closing, you would like to receive the notifications in the background thread instead of the main thread. In these cases, you must capture the notifications as they are delivered on the default thread and redirect them to the appropriate thread.

Upvotes: 6

Moayad Al kouz
Moayad Al kouz

Reputation: 1392

Tr run modified below showResult method:

func showResult() {
    resultMode = true

    self.containerView.frame.origin.y = CGFloat(1000)
    self.view.layoutIfNeeded()
    DispatchQueue.main.async {
        UIView.animate(
            withDuration: 3,
            animations: {
                self.containerView.frame.origin.y = CGFloat(200)
                self.view.layoutIfNeeded()
            } ,
            completion: nil
        )
    }
}

Upvotes: 3

Related Questions