Reputation: 269
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
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
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
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