Same view controller loads twice on click of button - ios

I want to show a controller as pop-up on click of a button. Suppose I have VC1 that has button, then on click of that the VC2 should load as a pop up. It is working to some extent. But I don't' know for what reason the VC2 is loading twice and the second time it loads it shows black background. Here is my code:
On click of button below function gets called in VC1,
VC2* childVC = [[VC2 alloc]init];
childVC.view.hidden = YES;
[self addChildViewController:childVC];
[self.view addSubview:childVC.view];
[self performSegueWithIdentifier:#"goToVC2" sender:self];
In VC2 viewdidload,
self.view.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.5];
How can I make VC2 appear as a pop up properly?

You don't need to segue and add the child view controller's view to the current view controller's view hierarchy. You should do one or the other. I would suggest the segue as that is a more apple approved approach. So change this:
VC2* childVC = [[VC2 alloc]init];
childVC.view.hidden = YES;
[self addChildViewController:childVC];
[self.view addSubview:childVC.view];
[self performSegueWithIdentifier:#"goToVC2" sender:self];
to
[self performSegueWithIdentifier:#"goToVC2" sender:self];

Related

How to set all tabbar are not active in ios?

In my app I have taken tabbar as a child view in my Homeviewcontroller screen using following code:-
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = #"Home";
UIViewController* controller = [self.storyboard instantiateViewControllerWithIdentifier:#"tabbar"];
[self addChildViewController:controller];
controller.view.frame = CGRectMake(0,60, self.view.bounds.size.width, self.view.bounds.size.height-200);
[self.view addSubview:controller.view];
[controller didMoveToParentViewController:self];
}
but my problem is, it shows the first tab active, and show the first tab content on Homeviewcontrller screen, but i don't want to any tab active on Homeviewcontrller , i only want to show tabbar on Homeviewcontrller. and when i click any tab it will show appropriate screen.
Is there any solution on that in objective-C?
That is not how UITabBarController works. There must always be one active tab, and corresponding view controller displayed.
You could add your HomeViewController to the UITabBarController and show its tab when app starts. Then you can switch between all the tabs including home.

UITabBar disappears after pushed to new view controller

I have an UITabBarController that has 3 buttons. The second button points to ViewController1 which is connected to another view called ViewController2. After I tap a button in ViewController2 I programmatically present ViewController1 again, that works perfect except one thing. After I "arrived" to ViewController1 the tab bar disappears.
I'm using this method to navigate back to ViewController1. (exactly I navigate to its navigation controller, but already tried with the view)
- (void)presentViewControllerAnimated:(BOOL)animated {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"storyboard" bundle:nil];
UINavigationController *firstViewNavigationController = [storyboard instantiateViewControllerWithIdentifier:#"destination"];
[self presentViewController:firstViewNavigationController animated:animated completion:nil];
}
I call here the first method
- (void)didTapButton:(id)sender {
UIButton *button = (UIButton *)sender;
CGPoint pointInSuperview = [button.superview convertPoint:button.center toView:self.tableView];
[self presentViewControllerAnimated:YES];
}
This method hides the tab bar in the ViewController2, I already tried without it, therefore there is no problem with it.
-(BOOL)hidesBottomBarWhenPushed
{
return YES;
}
I can't figure out why this thing happens, I think it's a fair solution, that worked well for a several times when I needed to present views. I've read it can happen with segues, but I'm doing it with code without segues.
Actually your code works right. There should not be tab bar when you present FirstViewController from SecondViewController. Because when you call instantiateViewControllerWithIdentifier its basically creates a new instance of that view controller, and of course, there is no tab bar.
The right way to go back to your first view controller is to pop SecondViewController (or dismiss it, if it presented modally). So your final code should be like this
- (void)didTapButton:(id)sender {
// If this view controller (i.e. SecondViewController) was pushed, like in your case, then
[self.navigationController popViewControllerAnimated:YES];
// If this view controller was presented modally, then
// [self dismissViewControllerAnimated:YES completion:nil];
}
And of course, your view controller hierarchy in storyboard must be like this:
-- UINavigationController -> FirstViewController -> SecondViewController
|
->UITabBarController____|
-...
-...
I've tried the same and got the same result.
My solution was simple, on the push do this :
UINavigationController *firstViewNavigationController = [storyboard instantiateViewControllerWithIdentifier:#"destination"];
firstViewNavigationController.hidesBottomBarWhenPushed = true; // Insert this and set it to what you want to do
[self presentViewController:firstViewNavigationController animated:animated completion:nil];
and then remove your
-(BOOL)hidesBottomBarWhenPushed
{
return YES;
}

Preserve Scroll Position When Pushing ViewController In Code in a Storyboard App

I have a storyboard app that has a few view controller that need to get pushed on the navigation stack programmatically, instead of with segues. I'm using the following code to do it:
POCollectionViewController* vc = [self.storyboard instantiateViewControllerWithIdentifier:#"categoryView"];
POCategory* destination = (POCategory*)self.collections[indexPath.row];
[vc setShowingCollection:destination];
[self.navigationController pushViewController:vc animated:YES];
My problem is that when I use segues to push view controllers and I press the 'back' button, the scroll position is preserved, but when I use the above code and press the 'back' button, my previous view controller appears with the scroll bar at the top.
Is it re-instantiating a view controller that is supposed to be already on the navigation stack? How can I preserve the scroll position?
EDIT
Code for setShowingCollection:
-(void)setShowingCollection:(POCategory*)collection
{
self->showingCollection = collection;
self.title = collection.name;
self.HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
self.HUD.delegate = self;
[self.HUD showWhileExecuting:#selector(buildDisplayItems) onTarget:self withObject:nil animated:YES];
}
The buildDisplayItems method fetches a bunch of the data from the server based on the showing collection's ID.
I think that you are not popping the controller correctly, your are not poping to the pushed controller, but popping to a newest controller. How you are doing the pop controller in your back button ?
you should do like this :
[self.navigationController popViewControllerAnimated:YES];
My immediate thought is if you must instantiate a new controller for every "segue" you will have to save the scroll position and when you reload the view cause the the uiscrollview to scroll.
Something like this saved in a property should do the trick:
CGRect scrolledRect = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, scrollView.bounds.size.width, scrollView.bounds.size.height);
Then when you reload:
[scrollView scrollRectToVisible:scrolledRect animated:NO];

UIBarButtonItem registers click event next to button, not on button

I got the popup, used at 2 locations within my app, one time in a navigation controller one time without navigation controller,
i got one button in a uitoolbar (select button) but this button has it's own life for some reason
The one in the navigation controller is working perfectly.
But the one called without navigation controller resizes this popup so i resized it back in the code like
- (void)showModal:(UIViewController *)controller
{
[controller setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:controller animated:NO completion:nil]; //Method used without navigationcontroller
[controller.view setBounds:CGRectMake(0,0, 600, 748)]; //resize => button doesn't work at all
//[controller.view setFrame:CGRectMake(0, 0, 600, 748)]; //resize => button only registers click event left from the actual button
//[[NSNotificationCenter defaultCenter] postNotificationName:#"show modal" object:controller]; // Method used within navigationcontroller
}
I've been looking all over google but i can't find anything on this problem.
Hope I have more luck here.
Probably the easy way to sort this problem out is to put it in a UINavigationController and use that to pop up. Then you don't have to use a UIToolBar.
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewControllerToPopUp];
[viewController setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentModalViewController:navController animated:YES];
This way the viewController you are presenting stays simple and you already know the button works when it is a navigation controller :)

Switching between view controllers

I have three view controllers. I used the flipsideproject template and then added another view controller.
There is a button on the first view controller that goes to the second view controller. There is a button on the second view controller that goes back to the first one. When switching between the first and second, those buttons always work.
It is the same situation with the second and third view controller. When I try to transfer between the first to second to third and then back to first, it does not work.
(1-->2-->3-->2-/->1) My poorly drawn diagram depicts the situation.
I had all of the back buttons connected to the back IBAction, which I thought was the problem. I then made another IBAction, but it has not fixed the problem.
1st view controller = MainViewController
2nd VC = FlipSideViewController
3rd VC = ChooseAlarmSound
This is for going 2->1 (this is the problem I think. It sometimes works)
- (IBAction)done:(id)sender
{
[self.delegate flipsideViewControllerDidFinish:self];
}
This is for going 2->3
- (IBAction)chooseSound:(id)sender
{
ChooseAlarmSound *controller = [[[ChooseAlarmSound alloc] initWithNibName:#"ChooseAlarmSound" bundle:nil] autorelease];
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:controller animated:YES];
}
This is for going 3->2
- (IBAction)goBack:(id)sender
{
FlipsideViewController *controller = [[[FlipsideViewController alloc] initWithNibName:#"FlipsideViewController" bundle:nil] autorelease];
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:controller animated:YES];
}
You presented your 3rd VC (going from 2 to 3) using modalviewcontroller. But then you tried to go back to 2nd VC (from 3rd to 2nd) using another modalVC. That will not let you go back to the previous instance of 2nd VC. You need to use dismissmodalviewcontrolleranimated method to do this. Checkout Apple website on modalviewcontroller class reference for detail info on this.
As suggested by user523234, all you need to do is call
[self dismissModalViewControllerAnimated:YES]
in the
- (IBAction)goBack:(id)sender
method of the 3rd view controller, instead of what you're doing, which is creating another instance of the 2nd view controller and presenting it.
The reason it's not working now, is because when you press the done button in the 2nd view controller it calls
- (IBAction)done:(id)sender
{
[self.delegate flipsideViewControllerDidFinish:self];
}
which is sending a message the 2nd view controller's delegate, which you haven't set in the case where you're going from 3->2.

Resources