I want to show UIActivityIndicatorView on my iphone when it changing the view.
I have written the following code:
- (void)viewDidLoad
{
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[spinner setCenter:CGPointMake(320/2.0, 460/2.0)]; // I do this because I'm in landscape mode
[self.view addSubview:spinner];
}
and on button's click event I want to change the view and in between that time I want to show that indicatorView So, I write
-(IBAction)buttonClick:(id)sender
{
[spinner startAnimating];
ViewController *lController = [[ViewController alloc] initWithNibName: #"View" bundle:nil];
self.viewController = lController;
[lController release];
//
[[self mainController] dismissModalViewControllerAnimated:YES];
[lViewController.view removeFromSuperview];
[self.view addSubview: lController.view];
[spinner stopAnimating];
}
It is not displaying the Indicator, So plz tell me where I am wrong?
UIActivityIndicator animates on the main thread (animation frames change per run loop). If you start, execute code, and stop, it never has a chance to animate (since it never exits the current run loop).
Try running your code on a background thread. This will allow the main thread to process animation frames.
In buttonClick it looks like you're adding the lController.view "on top" of the spinner (which was added earlier in viewDidLoad). It's hard to tell from your snippet what's going on with the modal dismissal so let's assume that's not the culprit.
You could try either calling [self.view bringSubviewToFront:spinner] after adding the new subview or else [self.view insertSubview:lController.view belowSubview:spinner] to put your view underneath the spinner. You may also want to set the hidesWhenStopped property on the spinner to YES so it automatically hides when you stop it.
Another thing to keep in mind is that loading and switching views may not actually take that long, so the spinner may not appear if things happen too fast.
Related
I want to simply have a loop so that an object continuously moves across the screen at the bottom. Here is my code it should be pretty easy to understand.
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(spawnRocket) withObject:self afterDelay:2]; //delay before the object moves
}
-(void)spawnRocket{
UIImageView *rocket=[[UIImageView alloc]initWithFrame:CGRectMake(-25, 528, 25, 40)]; //places imageview right off screen to the bottom left
rocket.backgroundColor=[UIColor grayColor];
[UIView animateWithDuration:5 animations:^(){rocket.frame=CGRectMake(345, 528, 25, 40);} completion:^(BOOL finished){if (finished)[self spawnRocket];}]; //this should hopefully make it so the object loops when it gets at the end of the screen
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
After doing all this i click run and all i see is a white screen on my iphone 6.0 simulator
ps. im running xcode 4.5.1
A few things:
UIImageView *rocket=[[UIImageView alloc]initWithFrame:...
You're not assigning an image to the image view, the best way to do this is to use:
UIImage* image = [UIImage imageNamed:#"image.png"];
UIImageView *rocket = [[UIImageView alloc] initWithImage:image];
rocket.frame = CGRectMake(-25, 528, 25, 40);
(The root cause of your problem) You are not adding your UIImageView to your main view, hence it's not being displayed. In spawnRocket, you should do:
[self.view addSubview:rocket];
Note: Because you want this to be done in a loop, you're gonna have to make sure your memory management is in order.
I don't know whether you still want the rocket on screen after it's finished moving, but if not, remember to keep a reference to the UIImageView and removeFromSuperview when you're done (to prevent memory leaks).
Calling spawnRocket in viewDidLoad is probably not the best idea, it may not reach the screen yet when spawnRocket is called. Try calling it in viewWillAppear or viewDidAppear (whatever is best in your case)
[self performSelector:#selector(spawnRocket) withObject:self afterDelay:2];
You don't need to provide self within withObject:, you're not accepting any parameters within spawnRocket
You don't add the UIImageView to any parent view. It will just live in memory, but not be displayed. Add it to your view controller's view after creating it:
[self.view addSubview:rocket];
Is it possible to implement a smooth transition when the app loads, from the launch image to the first view?
The default behavior is on/off, with an immediate change: the launch image appears, then it instantaneously disappears to let the main view controller take place. I'd like to implement some fading or zooming in or out.
Is this possible?
Thank you!
There's no framework support, but you can get that result if you do it yourself, manually. Depending on what your launch image is, and what your UI looks like, you can do it in different ways, but basically: make your first view controller load and display your default.png image in an image view when it loads up. Then animate a fade out of that image to reveal your actual UI.
Modified Dancreek's answer to do it all in AppDelegate application:didFinishLaunchingWithOptions. I like this because the code is guaranteed to only run at app start, and it's not polluting any of the view controllers.
It's very simple:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// set up your root view and stuff....
//.....(do whatever else you need to do)...
// show the main window, overlay with splash screen + alpha dissolve...
UIImageView *splashScreen = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default.png"]];
[self.window addSubview:splashScreen];
[self.window makeKeyAndVisible];
[UIView animateWithDuration:0.3 animations:^{splashScreen.alpha = 0.0;}
completion:(void (^)(BOOL)) ^{
[splashScreen removeFromSuperview];
}
];
}
You are in luck. I just did this a few min ago. You need a splash screen. An image on your view that is exactly the same as your default image that the device loads. Then in your app have it dismiss with a fade animation called from the viewDidAppear function
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self performSelector:#selector(killSplashScreen) withObject:nil afterDelay:1.0];
}
- (void)killSplashScreen {
[UIView animateWithDuration:0.5 animations:^{splashScreen.alpha = 0.0;} completion:NULL];
}
We often use something called "splashView" to do this. It was written by Shannon Applecline and available under the CC license. You will have to do some Googling to find it.
//
// splashView.h
// version 1.1
//
// Created by Shannon Appelcline on 5/22/09.
// Copyright 2009 Skotos Tech Inc.
//
// Licensed Under Creative Commons Attribution 3.0:
// http://creativecommons.org/licenses/by/3.0/
// You may freely use this class, provided that you maintain these attribute comments
//
// Visit our iPhone blog: http://iphoneinaction.manning.com
//
I am adding a view that fades in that gives my user alerts like successful login etc. Unfortunately the view does not appear above the keyboard so half of it gets hidden because I am displaying it in the center.
case 401:
alertBezel = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:alertBezel];
// Make the customViews 37 by 37 pixels for best results (those are the bounds of the build-in progress indicators)
alertBezel.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]] autorelease];
alertBezel.mode = MBProgressHUDModeCustomView;
alertBezel.labelText = #"Unauthorized User!";
[alertBezel show:YES];
[alertBezel hide:YES afterDelay:1];
break;
I also tried getting the key window:
[[UIApplication sharedApplication] keyWindow]
No luck.
It sounds like you should really be using a UIAlertView. That will show up over the keyboard.
Below are some resources on customizing alert views:
how i can implement a custom UIAlertview with a progress bar and a cancel button?
http://www.skylarcantu.com/blog/2009/08/14/custom-uialertview-color-chooser/
You could animate it up, by modifying its property when the keyboard shows up, or when your user go to the next field.
I was hoping for some help on this as I'm really stuck after trying to fix it for a few days.
Basically, my app has an OpenGL ES animation called levelsView that is displayed as soon as it has opened. Here is the code that starts my animation on the view controller:
- (void)animate
{
levelsView.animationInterval = 1.0 / 60.0;
[levelsView startAnimating];
[levelsView release];
}
The view controller also has a Switch button that lets the user change the animation. The code that displays the other animation is below:
- (IBAction) Switch: (id) sender {
SnowFallViewController* vce = [[[SnowFallViewController alloc] initWithNibName:#"SnowFallViewController"
bundle:nil] autorelease];
[self presentModalViewController:vce animated:YES];
}
Also here is the view for the code that starts the second animation on the second view controller:
- (void)viewDidLoad {
[super viewDidLoad];
CGRect rect = [[UIScreen mainScreen] bounds];
window = [[UIWindow alloc] initWithFrame:rect];
GLViewController *theController = [[GLViewController alloc] init];
self.controller = theController;
[theController release];
GLView *glView = [[GLView alloc] initWithFrame:rect];
[window addSubview:glView];
glView.controller = controller;
glView.animationInterval = 1.0 / kRenderingFrequency;
[glView startAnimation];
[glView release];
[window makeKeyAndVisible];
}
Basically, the problem I'm having is that I cannot get both the animations to work in the same application i.e. when the application is loaded up the first animation works but when the user clicks on the Switch button they only get a blank screen instead of the second animation.
One thing I've noticed is that the second animation will work if I do not start the first animation i.e. if I got in my animation code and delete
[levelsView startAnimating]; then the second animation will work(but obviously the first one will not).
Anyone with any insight on how I can fix this so I can get both animations to work?
Thanks,
Dave
Assuming you're using a CADisplayLink inside your GLView to run your animation loop, it seems from experience that they have mechanisms inside CADisplayLink to make sure that it doesn't just keep issuing calls upon calls if you're not keeping up with the refresh rate. It's more than possible that logic confuses itself a little if you have multiple CADisplayLinks attached at once.
I'd strongly suggest you add:
- (void)viewDidAppear:(BOOL)animated
{
[glView startAnimation];
}
- (void)viewWillDisappear:(BOOL)animated
{
[glView stopAnimation];
}
Those tie into the built-in mechanisms surrounding presenting and dismissing a view controller — the view controller is being told in the first instance when its view did appear (ie, the transition in is finished) and in the second when its view is about to disappear (ie, just before the transition outward begins). By stopping and starting animation on your GL view based on whether your controller is visible you'll save a lot of processing and prevent your disparate OpenGL views from fighting with each other for rendering times.
I am using a tableview with custom cells and want to change the content of the tableview on a button click. I am using an activity indicator while the cells are loading data.
This is how I am creating the indicatorview
indicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(141.0, 190.0, 37.0, 37.0)];
indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
indicator.hidesWhenStopped = YES;
[[self tableView] addSubview:indicator];
But it appears as if the frame has no effect on the indicator. The indicator instead of displaying in the center of the table, appears in the navigation bar on the top left corner of the view.
I have no idea what is wrong with this and why this is happening. Can someone please help me out.
alt text http://www.freeimagehosting.net/uploads/95cbe49850.png
initWithFrame: is not the suggested method for creating a UIActivityInidcator. Taking a look at the API, you can see that to create a UIActivityIndicator, you should use
[[UIActivityIndicator alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
Then add it to your view and set its position with setCenter: as suggested by Pablo.
Also, adding it to a location in a table view will make it scroll with the table if the user scrolls up or down. If you put it in the table's superview instead, it will stay in place.
Try this:
activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 32.0f, 32.0f)];
[activityIndicator setCenter:CGPointMake(160.0f, 208.0f)];
[activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
[activityIndicator startAnimating];
Calling to setCenter should give the behavior you are expecting.
Good luck!