One my primary view, animations execute according to the delay and durations set. However, when I segue to a new view, the animations are all complete instantly. How is this? This only happens when this animations told to execute from code in the viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
setProgress()
}
// the function below annimates a circular progress view
func setProgress() {
var to:Double = ((360.0 / 4) * increment)
progressCircle.animateFromAngle(360.0, toAngle: to, duration: 5) { completed in
if completed {
print("animation stopped, completed")
} else {
print("animation stopped, was interrupted")
}
}
}
viewDidLoad occurs before the view is presented on screen, if you want to run animations you should probably run them in viewDidAppear so that the view is loaded on screen and the components are visible.
call setProgress() in viewDiDAppear
override public func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
setProgress()
}
Maybe you can add delay and keep it running on a timer after viewdidload event of controller. Therefore you may reach your goal and run the animations in the time that you want.
Related
I am trying to zoom to a button on a UIScrollView. The first function is one that I run if I segue to the vc, the second is run from a button in the view.
When running the second function it goes perfectly and centres correctly
On the first however, despite being identical code, it has an offset in the x of about 40-50 pixels (Shows a point left of the button, not any part of it) although this offset changes dependent on the button.
func moveScrollviewToRoom(){
scrollView.zoom(to: artButton.frame, animated: true)
}
#IBAction func moveScrollview(_ sender: Any) {
scrollView.zoom(to: artButton.frame, animated: true)
}
The function was called here:
override func viewDidLoad() {
super.viewDidLoad()
if moveToRoom != "" {
moveScrollviewToRoom()
}
Any help would be greatly appreciated
Cheers!
Two points...
1 - Views and subviews have not yet been positioned by auto-layout in viewDidLoad(), so the artButton.frame will not be correct.
2 - Calling any function that animates a view from viewDidLoad() won't give the desired results, because the view is not even visible yet.
Move your call to viewDidAppear():
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if moveToRoom != "" {
moveScrollviewToRoom()
}
}
I have the following code for a button in my application to test my implementation of NVActivityIndicatorView:
#IBAction func goButtonPressed(_ sender: Any) {
self.startAnimatingActivityIndicator()
sleep(2)
self.stopAnimatingActivityIndicator()
}
The view controllers in my application also have this extension:
extension UIViewController: NVActivityIndicatorViewable {
func startAnimatingActivityIndicator() {
let width = self.view.bounds.width / 3
let height = width
let size = CGSize(width: width, height: height)
startAnimating(size, message: "Loading...", type: NVActivityIndicatorType.circleStrokeSpin)
}
func stopAnimatingActivityIndicator() {
self.stopAnimating()
}
}
The loading animations work elsewhere in the same view controller (i.e., the viewDidLoad() function) but for some reason I'm unable to get the loading animation to work on this button. The button is connected correctly as the application does sleep for the appropriate amount of time, but the loading animations fail to run.
Thanks in advance for the help!
The Indicator won't spin because the main thread is asleep. Use a 2 second timer to turn off the spinning instead.
#FryAnEgg coming in with the solution! The sleep(2) was preventing the loading animations from running.
Here's my updated code:
#IBAction func goButtonPressed(_ sender: Any) {
self.startAnimatingActivityIndicator()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
self.stopAnimatingActivityIndicator()
}
}
I have a globalstate in my app. Depending on the state the GUI is different.
When I go from the start View A to View B I have globalstate 3
It should show an information screen, but it doesn't. BUT: When the View B has loaded only once and I jump from View C/D/E back to View B, then the code work perfectly. (You have to be in View A to get in View B.)
I use a lot dispatch_async(dispatch_get_main_queue.. that isn't good style, is it?
Why is my animation not loading at the beginning? What is good style? Thank you for answers and sorry for mistakes (english isn't my mothertongue)
override func viewDidLoad() {
super.viewDidLoad()
dispatch_async(dispatch_get_main_queue(), {
self.animateTheInformationViewWhenGlobalStateIsThree()
})
}
func animateTheInformationViewWhenGlobalStateIsThree() {
print("GLOGBALSTATE \(globalState)") //it is 3
if globalState == 3 {
setGlobalState(3)
dispatch_async(dispatch_get_main_queue(), {
GUITools.animateTheInformationView(self.tableView, animateBottomLayout: self.animationBottomConstraint, value: self.negativValue)
})
print("THE POSITIV VALUE THE NEGATIV")
}
//GUITools-Static-Class:
class func animateTheInformationView(tableView: UITableView, animateBottomLayout: NSLayoutConstraint, value: CGFloat) {
dispatch_async(dispatch_get_main_queue(), {
animateBottomLayout.constant += value
UIView.animateWithDuration(Constants.animationTime, animations: { () -> Void in
tableView.layoutIfNeeded()
},completion: {
(value: Bool) in
})
})
}
EDIT
With viewDidAppear it works. But the animation isn't a real animation. The tableView "jumps". So there is no sliding/animation.
I deleted all dispatch_async..
override func viewDidAppear(animated: Bool) {
self.animateTheInformationViewWhenGlobalStateIsSeven()
}
viewDidLoad() does not mean that your view is already visible. Since it's not visible yet you cannot apply animations to it.
viewDidLoad() is only meant to configure your view controller's view and set up your view hierarchy - i.e. to add subviews.
What you want to use is viewWillAppear() (or viewDidAppear()) to start your animation as soon as the view becomes (or became) visible.
Also all the dispatch_async calls are most likely unnecessary. You usually only need them when you are not on the main (= UI) thread. Simply remove them.
I have seen several answers here on stackoverflow but they are all diferent to what I really need, and also they are all in Objective C...
So what I have is an animation of an object called stick that starts up and then goes down to the screen. When I press a button, I want it to pause and I want the stick to be precisely at that spot!
Also, hand is the button that stops the animation, that only stops when hand and stick and overlap.
Here's my code:
#IBAction func touchHand(sender: UIButton) {
let stickPresentationFrame = (stick.layer.presentationLayer() as! CALayer).frame
if !CGRectIsNull(CGRectIntersection(stickPresentationFrame, hand.frame)){
println("sup")
}
}
override func viewDidAppear(animated: Bool) {
UIView.animateWithDuration(2, animations: {self.stick.center = CGPointMake(self.stick.center.x, 760)}, completion: nil)
}
Any ideas? Thanks
I am looking to update a UIView thats in a storyboard (and instantiated from the storyboard) when it loads in the app.
I need to position a few icons in a dynamic way (that the interface builder doesn't let me do quite yet). However, if I put my code in viewDidAppear or viewDidLoad, it seems to be getting called too late.
Here is what happens the first few second or two when the view loads:
And then a bit later it goes to the right position (as the code was called).
My question is where do I need to initialize the positions of these objects so they dont snap over a second later. viewDidLoad and viewDidAppear are too late? Why!? :)
override func viewDidAppear(animated: Bool)
{
initView()
_gridLines = false
}
func initView()
{
_cameraFeed.initAfterLoad()
//center the buttons on half distance between middle button and screen edge
var middleDistance:CGFloat = _swapButton.frame.origin.x + _swapButton.frame.width/2
_linesButton.frame.origin.x = middleDistance/2 - _linesButton.frame.width/2
_flashButton.frame.origin.x = middleDistance + middleDistance/2 - _flashButton.frame.width/2
_selectPhotos.frame.origin.x = middleDistance/2 - _selectPhotos.frame.width/2
}
Swift and objc answers welcome!
Try putting the code setting the frame in viewWillAppear instead of viewDidAppear.
Also, you should call the super.
override func viewWillAppear(animated: Bool) {
initView()
_gridLines = false
super.viewWillAppear(animated)
}