Im experimenting with iOS 8 Objective-c project to perform a segue to a view controller right when viewDidLoad is presented.
Then this recent new presented view should be dismissed by a 30 seconds countdown to return to the initial view controller.
What would be like the code to dismiss the view with a countdown ? A countdown interface would not be necessary, just the background code.
My initial view controller is called ConfViewController and will perform a segue right on viewDidLoad to BubbleViewController, this should be displayed for 30s then be dismissed to the first one again ConfViewController.
#implementation ConfViewController
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidLoad
{
[super viewDidLoad];
The BubbleViewController
#interface BubbleViewController ()
#end
#implementation MessagesViewController {
UIVisualEffectView *blurEffectView;
}
- (void)viewDidLoad
{
self.dataSource = self;
self.delegate = self;
[super viewDidLoad];
Thnx and cheers!
Putting this Code into your bubble view Controllers viewDidLoad or similar and it will dismiss itself after 30 seconds:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:nil];
});
A quick way to execute any code after some time is to use this snippet:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//code to be executed after a specified delay
});
Where you should place this code is up to you either in the presenters or in the presented controllers viewDidLoad.
How you should dismiss it depends on the way that you presented it.
Add below line of code in BubbleViewController's viewDidLoad method
//countdown can be according to requirement
[self performSelector:#selector(dissmissView) withObject:nil afterDelay:30];
Now description of dissmissView method and add these method also.
-(void)dissmissView
{
if (self.navigationController.presentingViewController)
{
//presented As ModaL
[self dismissViewControllerAnimated:YES completion:nil];
}
else if(self.navigationController)
{
//Pushed in navigation controller stack
[self.navigationController popViewControllerAnimated:YES];
}
else //added as subView
{
[self.view removeFromSuperview];
}
}
Related
I have an app in which I present a menu modally. Then, when the user selects a menu option, the menu dismisses itself and upon completion, presents another view modally according to what button the user selected.
This method worked flawlessly before, but since iOS 13 it behaves weirdly. Basically, it would not present the second view until the user touches the screen, and I cannot for the life of me find out why it behaves this way.
Here is my code (I added logs where the flow stops):
- (void) dismissPopUpMenu:(UIButton *)sender {
[self dismissViewControllerAnimated:NO completion:^{
if ( (sender.tag == 13 ) {
[self openPopUpWindow:sender];
}
}];
}
- (void) openPopUpWindow:(UIButton *)sender {
interactionDisabledLayer.alpha = 1.0f;
PopUpViewController *popUpController = [[PopUpViewController alloc] initWithPopUp:sender.tag];
popUpController.delegate = self;
NSLog(#"We get to here without problems.");
[self presentViewController:popUpController animated:NO completion:^{
NSLog(#"It only enters here if we touch the screen.");
self->interactionDisabledLayer.alpha = 0.0f;
}];
}
Update: Delaying the code with a timer help, but I consider it a dirty hack and would like to find a better solution.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self presentViewController:popUpController animated:NO completion:^{
self->interactionDisabledLayer.alpha = 0.0f;
}];
});
Delaying the code that presents the second UIViewController with a timer seem to help, but it is a rather dirty hack, and I would like to find a better workaround. If anyone has a proper solution, please post it as an answer and I will accept it as best.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self presentViewController:popUpController animated:NO completion:^{
self->interactionDisabledLayer.alpha = 0.0f;
}];
});
What I need
I'd like to show an UIAlertView "Loading..." when I tap on a tab in my tabBar.
Reason why I want to do that
This is because that particular tab contains a UIWebView and is very slow, so when I tap on that tab it seems like my app is doing absolutely nothing for a few seconds. It is very ugly, so I'd like to show something to make the user know that the app is actually working.
Questions
In which position do I have to put it? If I write it in the ViewDidLoad, the AlertView is shown after those orrible few seconds. Is AlertView the best choice?
Thank you all.
add MBProgressHUD to your UIWebView viewDidLoad method
- (void)viewDidLoad {
[super viewDidLoad];
self.webView.delegate = self;
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Loading...";
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[hud hide:YES];
}
UIAlerView is not a good idea.
//Delegate method of UIWebView
- (void)webViewDidStartLoad:(UIWebView *)webView
{
if(![[UIApplication sharedApplication] isNetworkActivityIndicatorVisible])
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}
}
//Delegate method of UIWebView
- (void)webViewDidFinishLoad:(UIWebView *)webView_
{
if([[UIApplication sharedApplication] isNetworkActivityIndicatorVisible])
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
}
Set your tabBar as a delegate on viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
//Setting tabBarController as a delegate
self.tabBarController.delegate = self;
}
On your interface at .h method add delegate <UITabBarControllerDelegate>
Implement this function and add your loading view, for each time that you press tabBar. The method below gets executed always when the user taps an item on tabbar.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
//Show loading form here
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
// Do something...
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
});
}
P.S You need to add this method and set to delegate to every viewController which you need to show the alert view (Loading View)
For a loading view you can also load use MBProgressHUD as KingBabar pointed out. It has great features.
I am new to iOS Programming and now i have a problem.
There is a login screen that use [self presentViewController:loginview animated:YES completion:nil]; to show it out in MasterViewController.
And now i want to call a method (reload data) after [self dismissViewControllerAnimated:YES completion:nil]
this is my code:
[self dismissViewControllerAnimated:YES completion:^ {
[self getPostData]; // Reload Data
[self.tableView reloadData]; // Reload Data
}];
but it is not working.
(the reload method is in the MasterViewController)
Anyone can help me?
You can use NSNotificationCenter for your problem.
Define a NSNotification in your MasterViewController viewDidLoad like below
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(closeModal:) name:#"CloseModal" object:nil];
And then define the method as below
-(void)closeModal:(NSNotification *)notification{
UIViewController *controller=(UIViewController *)notification.object;
[controller dismissViewControllerAnimated:YES completion:^ {
[self getPostData]; // Reload Data
[self.tableView reloadData]; // Reload Data
}];
}
And at last from your other controller from where you are actually trying to dismiss your controller use code below
[[NSNotificationCenter defaultCenter] postNotificationName:#"CloseModal" object:self];
what you should do is basically call method on presenting view controller as below
[(MasterViewController*)self.presentingViewController reloadData];
You can call the presentingViewController's methods which updates the Presenting view.
for example: I have a modal view which can be launched from multiple Views. And all the presenting views have the view reloading code within view will appear.
Add the below code before dissmissing the modal view.
[self.presentingViewController viewWillAppear:YES];
[self dismissViewControllerAnimated:YES completion:Nil];
I am trying to create an app that has a navigation bar at the bottom of the first view controller. When the user presses next they are taken to the second view controller in the storyboard. I would like to know if it is possible to make the program automatically take the user back to the first view controller after 10 seconds? I am very new to xcode so any help implementing this in a simple fashion would be greatly appreciated
just create a function and call that after time delay and push in that
in second viecontroller
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(yourMethod) withObject:nil afterDelay:10.0];
}
-(void)yourMethod
{
//[self.navigationController popViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
hope this will help you
Add the below to viewDidLoad in your second view controller
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:#selector(viewWillDisappear:) withObject:nil afterDelay:2.0];
//I have given 2 seconds. you can change as your wish
}
Add this method too below.
-(void) viewWillDisappear:(BOOL)animated{
[self dismissViewControllerAnimated:YES completion:nil];
}
Hope it works..
Is is possible to have a UIView preloaded so that it will load faster when the user taps on button to load it? Currently I've got a library of informaiton that I'm attempting to load when the user taps a button, and for now it seems to be "ok" , but it makes the navigation to the page choppy, because of all the information in the library it's loading.
Thanks in advance!
It should be possible to split the setup of a View Controller from code that displays the view after a button is pushed. This will eliminate the lag when the button but the task to setup the view controller still need to be done sometime during execution (You can for example put it in the ViewdidAppear method so it is executed while waiting for the button to be pushed.
Take this code for example:
-(IBAction) button_pushed {
/*setup */
NewVC *vc = [[NewVC alloc] init];
vc.var1 = var1;
vc.var2 = x;
[vc setup];
/*display */
[self.navigationController pushViewController:vc animated:NO];
return;
}
You can split the code that setup the view from the code that displays the view
into :
#synthesize vc;
…..
- (NewVC) setup {
//setup
NewVC *vc1 = [[NewVC alloc] init];
vc.var1 = var1;
vc.var2 = x;
[vc setup];
return(vc1);
}
-(void) ViewDidAppear {
if (setupready) {
vc = [self setup];}
return;
}
-(IBAction) button_pushed:(ID) sender {
//display
[self.navigationController pushViewController:vc animated:NO];
return;
}