I'm trying to add a "loading" indicator in the center of my screen after each tab is selected and as the initial tab is loaded. I have found many posts showing the code to accomplish this but it doesn't seem to work with the way my webview app is setup.
I am a novice and have written all of my code from different tutorials, so If you could please explain where to put the code that would be helpful.
Here is my current .h file
#import <UIKit/UIKit.h>
#interface ViewController1 : UIViewController
{
IBOutlet UIWebView *myWebView;
}
#end
Here is my current .m file
#import "ViewController1.h"
#interface ViewController1 ()
#end
#implementation ViewController1
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Home", #"Home");
self.tabBarItem.image = [UIImage imageNamed:#"birdhouse"];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
{
UIImage *navigationBarBackground = [[UIImage imageNamed:#"navbar.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:navigationBarBackground forBarMetrics:UIBarMetricsDefault];
}
// Do any additional setup after loading the view from its nib.
NSURL *myURL = [NSURL URLWithString:#"http://jbirdmedia.org/rcwc/iphone/home.html"];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myURL];
[myWebView loadRequest:myRequest];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I've taken out all the code from my failed attempts so this code is currently my working app for viewcontroller1 and I have 4 ViewControllers for my 4 tabs.
Thanks,
Jason
Well your code right now doesn't mention anything about an UIActivityIndicatorView. In your viewDidLoad method you need something like this:
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityView.center = myWebView.center;
[myWebView addSubview: activityView];
[activityView startAnimating];
This is very rough and not tested but it should look something like this:
UIView *loadingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 150)];
loadingView.center = self.view.center;
[loadingView setBackgroundColor:[UIColor blackColor]];
[loadingView setAlpha:0.75f];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.frame = CGRectMake(0,0,40,40);
activityIndicator.center = loadingView.center;
[loadingView addSubview:activityIndicator];
[activityIndicator startAnimating];
UILabel *loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, loadingView.bounds.size.width, 50)];
[loadingLabel setText:#"Loading"];
[loadingLabel setBackgroundColor:[UIColor clearColor]];
[loadingLabel setTextAlignment:NSTextAlignmentCenter];
[loadingLabel setTextColor:[UIColor whiteColor]];
[loadingView addSubview:loadingLabel];
[self.webView addSubview:loadingView];
You'll need to adapt for the way you actually want the views to look, but that should get you pointed in the right direction.
Related
I use UITapGestureRecognizer to handle An ImageviewTap actions. In the main ViewController it works great. But when i Use another ViewController in my APP, and copy the same UITapRecognizer code I get an EXC_BAD_ACCESS code=1 address: 0x80759d3a error message to the line when i add the recognizer to my imageview. What do I wrong?
My ImageView: It works
UIImageView *live;
live = [[UIImageView alloc]initWithFrame:CGRectMake(92, 230, 136, 100)];
live.image = [UIImage imageNamed:#"online.png"];
[live addSubview:onlineLabel2];
[live setUserInteractionEnabled:YES];
[self.view addSubview:live];
[super viewDidLoad];
and my Gesture Recognizer:
UITapGestureRecognizer *singleTaP3 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onlineTap:)];
singleTaP3.numberOfTapsRequired = 1;
singleTaP3.numberOfTouchesRequired = 1;
[live addGestureRecognizer:singleTaP3];
and the last line i get the crash.
It sounds like your live view is not retain, so when you try to add the gesture, the view doesn't exist anymore. Try to record your live view as a property in your interface, and synthetise it in your implementation.
I am not sure if that this causing you to crash your code but you should call
[super viewDidLoad];
at the start of the code. (If you are using ARC than this looks fine.)
[super viewDidLoad];
UIImageView *live;
live = [[UIImageView alloc]initWithFrame:CGRectMake(92, 230, 136, 100)];
live.image = [UIImage imageNamed:#"online.png"];
[live addSubview:onlineLabel2];
[live setUserInteractionEnabled:YES];
[self.view addSubview:live];
I test the following and it works.
The interface:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) UIView *v;
- (void)tapAction;
#end
And the implementation:
#import "ViewController.h"
#implementation ViewController
#synthesize v=_v;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_v = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
[_v setBackgroundColor:[UIColor redColor]];
[self.view addSubview:_v];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapAction)];
tap.numberOfTouchesRequired = 1;
tap.numberOfTapsRequired = 1;
[_v addGestureRecognizer:tap];
}
- (void)tapAction
{
NSLog(#"tap tap");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
My problem was in my main viewcontroller. I called the new viewcontroller wrong, and get nullpointer for it. Get it in property, and it works. The problem is not with gesturetaprecognizer.
I have multiple view controllers in my application.
While downloading data from server, I can start a UIActivityIndicatorView.
But the problem is for three different view controllers I need to create three different UIActivityIndicatorView.
I want to initialize UIActivityIndicatorView only once in some place so I can display or hide it. No need to create or initialize UIActivityIndicatorView as many as view controllers.
How can I do this? Any help.
Add your loading indicator on window in your appdelgate like this
First initialize your loading view
-(void)InitializeLoadingIndictor
{
loadingView = [[UIImageView alloc]initWithFrame:CGRectMake(300, 400, 150, 150)];
[loadingView setBackgroundColor:[UIColor blackColor]];
[loadingView setAlpha:0.6];
[loadingView setHidden:YES];
[loadingView.layer setCornerRadius:10];
[_window addSubview:loadingView];
loadingIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[loadingIndicator setFrame:CGRectMake(50, 50, 50, 50)];
[loadingView addSubview:loadingIndicator];
}
Then create two methods two hide and show it
+ (void)showLoading
{
[loadingView setHidden:NO];
[loadingIndicator startAnimating];
}
Hide it
+ (void)hideLoading
{
[loadingView setHidden:YES];
}
Then in your view controller, call it as
[AppDelegate showLoading];
And to hide it when your are done
[AppDelegate hideLoading];
You can use a custom UIAlertView to show your indicator.
I have made two custom files using which you can show indicator without initializing it again and again.
files are:
//header file..
#import <UIKit/UIKit.h>
#interface ProgressIndicator : UIAlertView
{
UIActivityIndicatorView *activityIndicator;
}
#end
//implementation file
#import "ProgressIndicator.h"
#implementation ProgressIndicator
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
activityIndicator=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
// Initialization code
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
[self addSubview:activityIndicator];
[activityIndicator startAnimating];
// Drawing code
}
#end
//using this files in your controller..
#import "ProgressIndicator.h"
ProgressIndicator *progressIndicator=[[ProgressIndicator alloc] initWithTitle:#"Loading" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
[progressIndicator show];
Please refer this https://github.com/jdg/MBProgressHUD link. You will get custom Activity indicator for all the views.
Thanks guys for the answers. Below code works for me.
AppDelegate.m
-(void)StartLoading
{
loader = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
loader.frame = CGRectMake(50, 14, 20, 20);
[loader startAnimating];
[self.window addSubview:loader];
[self.window bringSubviewToFront:loader];
}
-(void)EndLoading
{
for(UIView *subview in [self.window subviews])
{
if(subview==loader)
[subview removeFromSuperview];
}
}
I am trying to change the background color and make an image appear on the screen when a button is pushed. I can get the color to change, but I can't get a trace of the image to appear. I don't know how to place the image on the screen either. I am using iOS 5 and storyboard, but I have not added the UIImageView to the storyboard, as I want it to appear.
My ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
- (IBAction)changeButton:(id)sender;
#end
My ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)colorchange
{
self.view.backgroundColor = [UIColor greenColor];
}
-(void)imageShow
{
UIImage *image = [UIImage imageNamed:#"logo-tag-centered.pmg"];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[imgView setImage:image];
}
- (IBAction)changeButton:(id)sender
{
[self colorchange];
[self imageShow];
}
#end
Any help would be greatly appreciated! Thanks!
You have to add the image view to your view controller's view.
- (void)showImage
{
UIImage *image = [UIImage imageNamed:#"logo-tag-centered.png"];
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.center = CGPointMake(self.view.bounds.size.width / 2.0f, self.view.bounds.size.height / 2.0f);
[self.view addSubview:imgView];
}
You haven't added the image view anywhere to the main view. You could do this:
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *image = [UIImage imageNamed:#"logo-tag-centered.pmg"];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[imgView setImage:image];
[imgView setHidden:YES];
[self.view addSubview:imgView];
}
-(void)imageShow
{
[imgView setHidden:NO];
}
- (IBAction)changeButton:(id)sender
{
[self colorchange];
[self imageShow];
}
How do I change the black/gray color to white?
This is just a simple view with a UIView attached to the UIViewControllers property together a with a webview that fills the UIView.
UPDATE
Here's the code that works:
- (void)loadView {
UIWebView *webview = [[UIWebView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 416.0f)];
[webView setBackgroundColor:[UIColor whiteColor]];
self.view = webView;
[webview release];
}
Thanks in advance.
You can use the UIScrollView's backgroundColor property to achieve this, the signature being:
#property(nonatomic, copy) UIColor *backgroundColor
As such to change it to white, you'd use:
[myScrollView setBackgroundColor:[UIColor whiteColor]];
A few improvements for your code:
- (void)viewDidLoad {
[super viewDidLoad];
UIWebView *webview = [[UIWebView alloc] initWithFrame:CGRectMake(self.view.bounds)];
[webView setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview: webView];
[webview release], webview = nil;
}
Overall you should find this approach less brittle.
PS. If you keep a reference to the UIWebView around, don't forget to release it in - viewDidUnload.
All of the examples I've seen on here and other sites involved creating a UIActivityIndicatorView and loading it with something like:
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithCustomView:myActivityIndicatorView
target:nil
action:nil]
autorelease];
However, that just creates a plain activity indicator in the navigation bar. What I want to do is have a button that looks just like the normal UIBarButtonSystemItem buttons but with an activity indicator instead of one of the default images. I've tried doing initWithImage and initWithTitle with nil images or titles and then adding the activity indicator as a subview, but that doesn't work.
Any ideas?
My Solution is to create a subclass of UIButton:
in SOActivityButton.h:
#interface SOActivityButton : UIButton
{
UIActivityIndicatorView* activityIndicator;
}
#end
in SOActivityButton.m:
#implementation SOActivityButton
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
CGRect innerFrame = CGRectInset(frame, 8.0f, 8.0f);
activityIndicator = [[UIActivityIndicatorView alloc]
initWithFrame:innerFrame];
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
[self addSubview:activityIndicator];
}
return self;
}
- (void)dealloc
{
[activityIndicator release], activityIndicator = nil;
[super dealloc];
}
- (void) startAnimating
{
[activityIndicator startAnimating];
}
- (void) stopAnimating
{
[activityIndicator stopAnimating];
}
#end
Then to use it:
SOActivityButton* activityButton = [[SOActivityButton alloc]
initWithFrame:CGRectMake(0.0f, 0.0f, 32.0f, 32.0f)];
[activityButton setImage:[UIImage imageNamed:#"button-background.png"]
forState:UIControlStateNormal];
[activityButton addTarget:self action:#selector(myAction:)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *activityBarButtonItem = [[UIBarButtonItem alloc]
initWithCustomView:activityButton];
[activityButton release];
self.navigationItem.rightBarButtonItem = activityBarButtonItem;
[activityBarButtonItem release];
You will need to find or create a button-background.png. The PSD here should have one.
have you tried creating a UIButton in the button bar and then adding an activity indicator as a subView of the UIButton?
I have this working and it is very simple. Just place the activity indicator where you want it with IB, but make sure it's lower in the list than the bar you want it on, and is at the "top level" (not a subview of anything else). Then control it in code via an outlet.
Here's something that can help:
activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[activityIndicator startAnimating];
UIBarButtonItem *activityItem = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
[activityIndicator release];
self.navigationItem.rightBarButtonItem = activityItem;
[activityItem release];
[activityIndicator startAnimating];