i have a Problem with my Activity Indicators. I have an Button which reload a Website and Display between a Activity Indicator. The Problem is if the User hits more than 1 Times on the Button it will rebuild a new Indicator and this Indicator freezes on the Screen all the Time.
Button disabling is not working. Has anyone a Solution for this Problem. Please help.
Here is my Code:
-(IBAction) buttonReload {
Reachability *r = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN)){
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:#"No Inet!" message:#"You need a Inet Connection..."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[myAlert show];
[myAlert release];
}
else
{
//Website loading
[self performSelector: #selector(doLoadWebsite)
withObject: nil
afterDelay: 0];
return;
}
}
- (void) doLoadWebsite
{
//add activity indicator
NewsActivity = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(140.0f, 180.0f, 40.0f, 40.0f)];
[NewsActivity setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
[self.view addSubview: NewsActivity];
[NewsActivity startAnimating];
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(finishActivity) userInfo:nil repeats:YES];
//NewsActivity.backgroundColor = [UIColor grayColor];
NewsActivity.hidesWhenStopped = YES;
// Show Status Bar network indicator
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//perform time-consuming tasks
//load News Website
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
}
-(void) finishActivity {
if (!webView.loading) {
[self.NewsActivity removeFromSuperview];
[NewsActivity stopAnimating];
//Hide network activity indicator
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
else {
[NewsActivity startAnimating];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
}
You should perform stopAnimating , removeFromSuperView once the page is loaded. If the user refreshes the page again, you can again add it to the subView and startAnimating.
Related
I have a UIViewController with a UITableView in it. I add a UIView as a subview on top of that. When I press one of the UIButtons on the subview, there is a noticeable lag. How do I make it faster?
See video: http://www.youtube.com/watch?v=KWy6NrZUeqA&feature=youtu.be
- (IBAction)tweetThat:(id)sender {
[MBProgressHUD showHUDAddedTo:self.socialMediaView animated:YES];
dispatch_queue_t queueOne=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_sync(queueOne, ^{
NSString *tweetBody=#"BLABLABLATweet";
if ([TWTweetComposeViewController canSendTweet])
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
[tweetSheet setInitialText:tweetBody];
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.controllerView animated:YES];
[self presentModalViewController:tweetSheet animated:YES];
});
}
});
}
I've used the dispatch method you tried above, but with a few changes. It has really made the experience a lot better. "loadingView" is as named, just a loading view that displays before the tweet view comes up.
loadingView.hidden = NO;
[loadingView setNeedsDisplay];
if ([TWTweetComposeViewController canSendTweet])
{
double delayInSeconds = 0.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
TWTweetComposeViewController *tweet = [[TWTweetComposeViewController alloc]init];
[tweet setInitialText:#"I'm using a new app called TickTalk to help my speaking cadence. Check it out!"];
[tweet addURL:[NSURL URLWithString:#"http://www.ticktalkapp.com"]];
TWTweetComposeViewControllerCompletionHandler
completionHandler =
^(TWTweetComposeViewControllerResult result) {
switch (result)
{
case TWTweetComposeViewControllerResultCancelled:
NSLog(#"Twitter Result: canceled");
break;
case TWTweetComposeViewControllerResultDone:
NSLog(#"Twitter Result: sent");
break;
default:
NSLog(#"Twitter Result: default");
break;
}
loadingView.hidden = YES;
[self dismissModalViewControllerAnimated:YES];
};
[tweet setCompletionHandler:completionHandler];
[self presentModalViewController:tweet animated:YES];
});
}
else
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Sorry" message:#"Your device is not setup to tweet" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
loadingView.hidden = YES;
}
change your dispatch_sync to dispatch_async. what is the point of dispatching to the background if you are going to lock up the UI until it returns.
The lag is from TWTweetComposeViewController. There is nothing you can do about it because its a system optimization. You'll probably notice the second and third times you hit the button the lag it gone.
I have one UIAlertView containing one UITextField with ok and cancel button. When I click on ok button i am calling webService. I want to return keyboard before calling webservice. Keyboard is not returning till response is not coming from webservice. Because of that half screen not visible to user during loading webservice. Here is my code which i did.
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Forgot Password" message:#" " delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
// Adds a username Field
alertEmailtextfield = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 45.0, 260.0, 29.0)];
alertEmailtextfield.layer.cornerRadius = 07.0f;
[alertEmailtextfield setBorderStyle:UITextBorderStyleRoundedRect];
alertEmailtextfield.placeholder = #"Enter Email";
[alertEmailtextfield setBackgroundColor:[UIColor whiteColor]];
alertEmailtextfield.autocapitalizationType =UITextAutocapitalizationTypeNone; //For Making Caps Off
[alertview addSubview:alertEmailtextfield];
[alertview show];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
if ([alertEmailtextfield.text length] != 0) {
if (![self validEmail:alertEmailtextfield.text]) {
[AlertView UIAlertView:#"Enter email is not correct"];
}else{
//[alertEmailtextfield resignFirstResponder];
[NSThread detachNewThreadSelector:#selector(startSpinner) toTarget:self withObject:nil];
Boolean isForgotPassword = [serverConnection forgotPassword:alertEmailtextfield.text];
if (isForgotPassword) {
NSLog(#"Mail is send");
[AlertView UIAlertView:#"New password is send to your mail"];
[spinner stopAnimating];
}else{
[AlertView UIAlertView:#"User does not exist"];
[spinner stopAnimating];
}
}
}else{
[AlertView UIAlertView:#"Text Field should not be empty"];
}
}
}
Please if any one knows how to return keyboard in UIAlertView's UITextField, help me.
Your UI is stuck waiting for your webservice to complete. Call your webservice in a background thread your problem will be solved.
[self performSelectorInbackgroundThread:#selector(yourWebservice)];
Might be u are doing both task (webservice call and keyboard resinging) in same main thread so untill ur data is not loading from server keyboard is not resign from view. call weservice method in background thread like.
-(void)alertView:(CustomAlert *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[textField resignFirstResponder];
UPdate
[self performSelectorInBackground:#selector(yourWebservice) withObject:nil];
}
When you call the following twitter method I always get a strange indentation on top.
Here is my method:
- (void)twitter {
if ([TWRequest class]) {
TWTweetComposeViewController *twitter = [[TWTweetComposeViewController alloc] init];
[twitter setInitialText:titleDetail];
[twitter addImage:imgPreview];
[twitter addURL:[NSURL URLWithString:linkPost]];
[self presentViewController:twitter animated:YES completion:nil];
twitter.completionHandler = ^(TWTweetComposeViewControllerResult res) {
if (res == TWTweetComposeViewControllerResultDone) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Выполнено" message:#"Ваш твит успешно опубликован" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
} else if (res == TWTweetComposeViewControllerResultCancelled) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Ошибка" message:#"Ваш твит неопубликован" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
[self dismissModalViewControllerAnimated:YES];
};
}
}
How do I fix this?
Update: FIXED
The problem was this:
When the application loads (which displays a splash screen) I hide the status bar.
The status bar is initially hidden.
And then, in AppDelegate.m:
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
[UIApplication sharedApplication].keyWindow.frame = CGRectMake(0, 20, 320, 460);
The problem was precisely in 20:
CGRectMake (0, 20, 320, 460);
The problem was this: When load application (which displays splash screen) I hid status bar.
Status bar is initially hidden YES
And then, in AppDelegate.m:
[[UIApplication sharedApplication] setStatusBarHidden: NO withAnimation: NO];
[UIApplication sharedApplication]. KeyWindow.frame = CGRectMake (0, 20, 320, 460);
The problem was precisely in 20:
CGRectMake (0, 20, 320, 460);
In my view, I have an actionsheet that may be presented from a UIBarButton (iPad). If user goes to homescreen and back, app shows a lock screen wehre user must enter password for security. But if the popover wasn't dismised before going into background, it is still showing on top of lockscreen. The UIActionSheet is a property of that VC, not the App Delegate.
The method in my delegate is:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(#"STATUS - Application did become active");
[[UIAccelerometer sharedAccelerometer] setDelegate:nil];
[_notActiveTimer invalidate];
_notActiveTimer = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:#"_application_background" object:self userInfo:NULL];
LockScreen *vc = [[[LockScreen alloc] initWithNibName:#"LockScreen" bundle:nil] autorelease];
vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
vc.showFullUsernamePasswordLogin = TRUE;
[self.splitView presentModalViewController:vc animated: YES];
}
Code:
- (IBAction)showeRXActionSheet:(id)sender
{
if (self.actionSheet != nil) {
[self.actionSheet dismissWithClickedButtonIndex:0 animated:NO];
}
if (!self.eRXActionSheet)
{
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:#"eRX Menu" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"New eRX", #"eRX Refills", nil];
sheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
self.eRXActionSheet = sheet;
[sheet release];
[self.eRXActionSheet showFromBarButtonItem:sender animated:YES];
return;
}
[self.eRXActionSheet dismissWithClickedButtonIndex:self.eRXActionSheet.cancelButtonIndex animated:YES];
self.eRXActionSheet = nil;
}
- (IBAction)actionButtonClicked:(id)sender
{
if (self.eRXActionSheet != nil) {
[self.eRXActionSheet dismissWithClickedButtonIndex:0 animated:NO];
}
if (!self.actionSheet)
{
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:#"Action Menu" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Help", #"Lock", #"Log Out", nil];
sheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
self.actionSheet = sheet;
[sheet release];
[self.actionSheet showFromBarButtonItem:sender animated:YES];
return;
}
[self.actionSheet dismissWithClickedButtonIndex:self.actionSheet.cancelButtonIndex animated:YES];
self.actionSheet = nil;
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (actionSheet == self.eRXActionSheet)
{
if (buttonIndex == 0)
{
[self erxButtonClicked];
}
else if (buttonIndex == 1)
{
[self erxRefillButtonClicked];
}
}
else
{
if (buttonIndex == 0)
{
[self helpButtonClicked];
}
else if (buttonIndex == 1)
{
[self lockButtonClicked];
}
else if (buttonIndex == 2)
{
[self logOut];
}
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
self.eRXActionSheet = nil;
self.actionSheet = nil;
}
This should do what you want.
-(void)dismissSheet{
if (self.actionSheet){
[self.actionSheet dismissWithClickedButtonIndex:0 animated:NO];
}
}
-(void)viewDidLoad{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(dismissSheet) name:UIApplicationWillResignActiveNotification object:nil];
// Your other setup code
}
you could also use the UIApplicationDidEnterBackgroundNotification, what ever makes sense for you application flow.
remember to remove observer in dealloc.
i am using the simple alert view with two buttons names as ok,cancel.
when ever i press ok,cancel alert view quits as general.
But i need when ever i click alert view ok button with out quit alert view activity indicator
will run for 2 min on the same alert view and quit. when ever i click cancel it quits normally.
can any one please help me.
Thank u in advance.
You can modify the UI control events for the OK button, so that your own event handler is called for that button and the alert view won't be dismissed until the long-running task has finished.
In that event handler attach an activity indicator to the view and start your task asynchronously using GCD.
#import <dispatch/dispatch.h>
// ...
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Test" message:#"Message" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK" ,nil];
for (UIView *subview in alert.subviews)
{
if ([subview isKindOfClass:[UIControl class]] && subview.tag == 2) {
UIControl* button = (UIControl*) subview;
[button addTarget:self action:#selector(buttonOKPressed:) forControlEvents:UIControlEventTouchUpInside];
[button removeTarget:alert action:nil forControlEvents:UIControlEventAllEvents];
}
}
[alert show];
[alert release];
// ...
-(void) buttonOKPressed:(UIControl*) sender {
[sender removeTarget:self action:nil forControlEvents:UIControlEventAllEvents];
UIAlertView* alert = (UIAlertView*)[sender superview];
CGRect alertFrame = alert.frame;
UIActivityIndicatorView* activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.frame = CGRectMake(0,alertFrame.size.height, alertFrame.size.width,30);
activityIndicator.hidden = NO;
activityIndicator.alpha = 0.0;
activityIndicator.contentMode = UIViewContentModeCenter;
[activityIndicator startAnimating];
[alert addSubview:activityIndicator];
[activityIndicator release];
[UIView animateWithDuration:0.3 animations:^{
alert.frame = CGRectMake(alertFrame.origin.x, alertFrame.origin.y, alertFrame.size.width, alertFrame.size.height+50);
activityIndicator.alpha = 1.0;
}];
//alert.userInteractionEnabled = NO; // uncomment this, if you want to disable all buttons (cancel button)
dispatch_async(dispatch_get_global_queue(0,0), ^{
[NSThread sleepForTimeInterval:5]; // replace this with your long-running task
dispatch_async(dispatch_get_main_queue(), ^{
if (alert && alert.visible) {
[alert dismissWithClickedButtonIndex:alert.firstOtherButtonIndex animated:YES];
}
});
});
}