Swift 4 SVProgressHUD not showing on load - swift

I have installed cooapods and SVProgressHub. I am unable to figure out how to show the SVProgressHUB loading screen.
SVProgressHUD.show()
This is inside my view controller.
I am new to swift and stack overflow. Cheers!

You can Popssibly Try this:
SVProgressHUD.setDefaultStyle(.custom)
SVProgressHUD.setDefaultMaskType(.custom)
SVProgressHUD.setForegroundColor(UIColor.red) //Ring Color
SVProgressHUD.setBackgroundColor(UIColor.yellow) //HUD Color
SVProgressHUD.setBackgroundLayerColor(UIColor.green) //Background Color
SVProgressHUD.show()
The output:
Cheers!

Its not clear what you are asking, are you looking to call SVProgressHUD during the splash screen ? or when the first view controller is opening.
If there is nothing being processed between when you call .show and when you call .dismiss, it simply might not be seen, even though you are making the calls.
In AppDelegate didFinishLaunchingWithOptions you can place some defaults
SVProgressHUD.setBorderColor(kBrandBlue)
SVProgressHUD.setBorderWidth(1.0)
SVProgressHUD.setCornerRadius(44.0)
SVProgressHUD.setForegroundColor(.blue)
SVProgressHUD.setRingThickness(4.0)
SVProgressHUD.setGraceTimeInterval(0.5)
I'm not sure what the default grace timer is, but you might want to check that.
If you call .show and dont call .dismiss, then it will keep spinning forever, so just put the .show in viewDidLoad for your ViewController and see if it comes up.
Hope that helps

Related

UIImage animations don't work in a view pushed without animation

I've got a view controller whose view contains a UIImageView that does animation:
//AnimationViewController::ViewDidLoad event:
var ctlAnimations = new UIImageView();
ctlAnimations.AnimationImages = list.ToArray(); //<--list contains the UIImages
ctlAnimations.AnimationDuration = 1.0 * list.Count;
ctlAnimations.StartAnimating();
this.Add(ctlAnimations);
This works perfectly: when I push AnimationViewController onto the navigation stack, it displays and animates the UIImage.
But now I need to show AnimationViewController with a custom animated transition:
var transition = CATransition.CreateAnimation ();
transition.Duration = 0.3f;
transition.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
transition.Type = CATransition.TransitionFade;
this.View.Layer.AddAnimation (transition, "fade");
//viewController is being pushed with animated=false, because we have a custom animation
base.PushViewController (viewController, false);
this.View.Layer.RemoveAnimation("fade");
This also works perfectly, in that the new View transitions into place using the specified custom animation.
But when I push AnimationViewController onto the stack using an animated transition, it displays but the animation doesn't run. Instead, it shows the first frame of the animation (the first image in the list), and doesn't run it.
So, something about the transition is breaking the ability to animate a UIImage in the new view controller, but I simply can't figure out what to do about it.
Update: I've noticed that if I tap the NavigationController's back button, but then move off of the back button and let go (so I don't actually go back), the animation starts playing!
PushViewController works like this: Over the current view controller the next view controller is placed you can say pushed onto the stack. From Apple docs its clear that either you need to push view controllers either with animation or without.
Work around:
Set the frame of the next view controller's view's x position beyond
the screen's right
Suppose width of the screen is 320, then set the x position of next
view as 320.
Add the next view as subview to the existing one.
Now do your custom animation.
Another work around:(a bit more overhead though)
Take a snapshot programmatically of current view.
Add the snapshot image as the initial view of next view controller.
Now push view controller without animation. (User will still see the old view)
In viewDidAppear of new view controller start your custom animation.
[I have to warn you that this method of taking snapshot might give you a small delay in older devices. Newer devices are pretty fast enough you wont see any lag]
Let me know if any issues in case you are implementing any of these solutions.
Try putting the animating bit in ViewDidAppear rather than ViewDidLoad. Also, try using breakpoints and NSLogs to follow what happens after the animation, starting with the ViewDidLoad and ViewDidAppear. Try having the animation repeat forever so you can see if it has ever been animating or not.
I'm very curious what the culprit is here as well. Why is the animation not displaying correctly in some cases?
My theory is that you have placed animation code in viewWillAppear rather than viewDidAppear. Animation code does not run properly when placed in WILL or SHOULD methods.
Can you please post back what caused the issue?
Suspicion #1
I am betting that your code is not being called because it is in ViewDidLoad. I believe you are creating a customized view stack, that means you need to be using the ChildViewController methods from Cocoa.
I am unfamiliar with MonoTouch (I only write pure CocoaTouch), so this might not be 100% correct
I would be consoling out your viewDidLoad and viewDidAppear methods and absolutely make sure they are being called. It is my suspicion that viewDidLoad IS NOT. And this is causing viewDidLoad to not be called on the UIImageView.
In your code you probably need the equivalent of (from objective-c):
[self addChildViewController:viewController];
// OR?
[base addChildViewController:viewController];
This tells the 'parent' viewController that the Child has been made visible, so call the viewDidLoad/Appear and Unload/Disappear methods when appropriate. This might not exist in MonoTouch, or the Push methods might not be fully implemented, so you might need to do some hacky (bad) stuff like manually calling the viewDidLoad method manually.
Suspicion #2
It could also be that your 'list' variable (the one holding the images) is nil. If that happened the animation would not run. OR maybe it has something to do with the duration of your animation, try to set it to whatever would make it repeat forever. Be sure it isn't running REAL FAST somehow and you are just missing it.
begin philosophical musing
Either that or start learning actual Cocoa development :) Not meant as a flame, but definitely meant seriously, you are going to run into problems trying to develop applications through translation layers (custom language-bridges meant to get around writing the base language of a framework/application/platform).
Titanium/MonoTouch/PhoneGap will never produce as robust or high-quality applications as real Objective-C. And besides that, once you learn Cocoa it will change how you write everything else, and I doubt you will want to go back. As the wonderful website of the same name says, 'Cocoa is my girlfriend'
Let me tell the something about UI in IOS. In IOS access to the UI Elements is limited to a single thread.
The single thread would always be the mainThread except in the case when you are running an animation.
Hence when u are performing number of animation at the same instance you have to use
beginAnimation.
setFrame (or) some methods that changes state of UI element.
Repeat step2 for all those objects u are scheduling to animate.
comitAnimations to perform all animations at once. (using comit animations ensure all the animations are performed on same thread)
So, I guess here is what happening in ur case.
Viewcontroller started an animation to push the view controller into stack.
Image view started another animation before finishing first animation.
Look at the links to get a clear idea link1 and link2.
Well Let's get into the solution
Add an ivar and retained property named ctlAnimations to your class
In ViewDidLoad (or) ViewDidAppear
self.ctlAnimations = new UIImageView();
ctlAnimations.image=(UIImage*)[list.toArray() objectAtIndex:0];
this.Add(ctlAnimations);
[self performSelector:#selector(startAnimatingImage) afterDelay:0.1];
Create a private method named startAnimatingImage with below code
self.ctlAnimations.AnimationImages = list.ToArray();
ctlAnimations.AnimationDuration = 1.0 * list.Count;
ctlAnimations.StartAnimating();
On a brief we just shown first image for a moment when the firstanimation is taken place and then we delayed animation start for 1 second so that it performs after first animation and then starts animating the image.
Go ahead and give it a try
There is the concept for the Main thread. So UIAnimation are actually works on Main Thread and at the same time may be this was happen that another task is performing on the same Main Thread.So that was a case like IOS will give preference according to processes id of each process at a time and for the solution you need to make background thread for the same operations.
Well, I never figured out what the problem was here, but it also turned out that there was some sort of memory leak in UIImage such that on some phones my code was crashing.
So I rewrote it to do the animation manually. Now I set a timer and keep a frame index variable, and every time the timer rings I change the image myself. This amounts to the same thing, and it turns out it fixes this problem.

How can I optimize my controllers so they load faster?

Most of the iOS apps I use are very responsive, when I tap on an element it goes to the next view right away. In my app, some of my view controllers take 0.5-1.0 second to load.
My code is all in the viewDidLoad method and I'm pretty sure that's the problem but I can't move anything out since I need every single element that I instantiate.
A solution I thought is to move all the work I do in viewDidLoad in a thread then call the main thread when I'm ready to call addSubview, would that work even if UIKit is not thread safe? Or is there something else I'm missing?
Try to move some code you might have in viewDidLoad to viewdidAppear. viewDidAppear is being called once the view is presented. If you have to make some hard work, do it there and maybe show aa spinner somewhere while you do that.
What are you exactly doing in viewDidLoad? Btw remember that a view is only loaded when you need it, if you want to switch between views faster I can suggest you to create an initializion phase where you call -view on all the view controller you want to show, maybe helped with a spinner or a progress bar. but pay attention this would work only with intensive loading task and not memory consuming tasks. It sounds very strange your request, so is better the you try to explain better why your viewDidLoad is so slow, maybe there is something wrong.
Define your UI elements in Xcode as part of designing the interface. That way, Xcode can compile your storeyboard or xib files into the rapidly loading binary form.

"Unbalanced calls to begin/end appearance transitions" warning when push a view in a modal way in XCode 4 with Storyboard

After some research on the web without success, I come here to ask you the question about my warning.
Actually, I have a view V1 with a navigation controller and I want to push a modal view V2 when V1 has finished loading.
So I use the performSegueWithIdentifier method (I'm using storyboard).
Here is my code:
[self performSegueWithIdentifier:#"showConnexionViewSegue" sender:self];
And when I compile, I got this warning:
Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0x6849b30>
Can anyone help me?
It sounds like you may be performing the segue in -viewWillAppear: thus generating two -viewWillAppear: messages without 2 corresponding -viewDidAppear messages.
Try performing the segue in -viewDidAppear.
I had this problem, but what I had done is on a UIViewController I had linked a Segue from a UIButton and also coded it into a nextBtnPressed: function, so I was actually pushing two new UIViewControllers on the one button press. Limiting it to just the one segue fixed it. But it took some investigating to see that I had done this double up.
'Unbalanced calls to begin/end appearance transitions for '
Says an animation is started before the last related animation isnt done.
So, are you popping any view controller before pushing the new one ?
Or may be popping to root ? if yes try doing so without animation
i.e. [self.navigationController popToRootViewControllerAnimated:NO];
And see if this resolves the issue, In my case this did the trick.
The reasons for this are manifold and are very specific to the context and the programming. For example, what I was doing was
initialising a sound file, playing it (asynchronously) for 1.4 seconds,
making an image move across the screen using animation timed to last 1.4 seconds and,
with a timer set to 1.4 seconds after step 2, pushing a viewcontroller.
What i discovered is that if I DO NOT have the instructions for these 3 steps one after the other (if I mix them up), then I get the error "Unbalanced calls...". Also, if I time the push of the viewcontroller to less than 1.4 seconds, I get the message as well.
So, check that the sequence and timing of your program instructions are correct.

Where to put cleanup code in UIViewController?

I have a UIViewController subclass that loads a bunch of images for each cell in a tableview asynchronously which is handled by a separate download class. I keep a list of all of these download requests in a dictionary which is keyed to the index of the cell that is requesting the image.
My question is i where should i put the code that cancels the image download if the viewcontroller is popped off the navcontroller? I need to do this because if the user hits back while there are still images being downloaded (which could take a while) then when they are finished downloading the viewcontroller has already been released.
I cant put it in the viewWillDisappear method because i do not want to stop the download if the user clicks on a separate tab and only when the hit the back button. For now i put this code in the viewcontrollers dealloc method which works fine although it doesnt seem right for some reason. I thought of using the viewDidUnload method but it seems this is only called when there is a low memory warning?
Any ideas?
dealloc is the perfect place for this as the view controller gets deallocated and you are responsible to clean your stuff up.
You may want to consider putting the code in viewWillDisappear: anyway, after all if the screen you are navigating to needs anything loaded it will be slowed by the background image load...

How can I add a startup sound when UIViewController *controller is initiated?

ViewDidLoad doesnt work.
ViewDidappear Doesnt work.
No matter what happens, the sound is played then the viewController image is displayed.
What I want is the image to be displayed, then the sound plays simultaneously'
did you try viewWillAppear?
That could be because things happen in SEQUENCE unless you give explicit instructions that you want things to happen at the same time. If you want a sound to play WHILE an image is loading you need to use threads.
This guide explains how to accomplish that
I think viewWillAppear might work. viewDidLoad only gets called once, so it wouldn't get played every time a view controller is pushed.
I ended up making the sound effect have an extra 1 second pause at the beginning of it and playing it in viewdidappear. Not the perfect solution, but it was the easiest.
The sound was originally being played, before the phone actually rendered the viewcontroller, which I found counter intuitive seeing as the method 'viewdidappear' kinda sounds like the view should have erm already appeared.
Does that make sense?