i am using two view says A and B. I need to go to view B on pressing a button in View A so in the button action listener defined in view A, i wrote
-(IBAction)bt:(id)sender
{
B *mB=[[B alloc]initWithNib:#"B" bundle:nil];
[self.view addSubView:mB.view];
}
so that means view B has been added over view A. Thus, both the views remain on stack which consume memory i think.
Is their any way by which pressing the button in view A, it is removed and then view B is added??
you can use removeFromSuperview to remove view A
[view_A_Object removeFromSuperview];
Related
I have a tricky situation. The following is the hierarchy of the views that I have.
(Root)Navigation-VC-->View A-->(via Segue push)--> View B-->View C
(Root)Navigation-VC-->View A-->(via modal push)-->(Nav Controller) View D-->View E
There is a cancel button in view D. When I click on it, it correctly shows view A. But For some reasons I would want it to go to View B in the first navigation hierarchy. How can I do such transitions?
If I create a modal segue from view D to view B it destroys the navigation hierarchy that view B is part of. If I push view B from view D then view B becomes a part of a different hierarchy altogether.
Can it be done? Do I have to rethink the design?
Well, after you dismiss the modal view controller, you can always call the method performSegueWithIdentifier:sender: to push view B. Just remember to set the segue identifier in your storyboard.
Call the method dismissViewControllerAnimated:completion: in view A and call the perform segue at the completion block. This is just to avoid any corruption that might happen to the navigation controller if you dismiss and perform segue at the same time.
I have an app with one main TabBarController containing two tabs that control two different views, A & B. View A is a scrollView and View B is a TableView. When i initially load the app, the scrollview in view A is empty.
In order to add pages to my scrollView, I have set it up as follows: I go to view B and perform one modal segue to a view embedded with a navigationBar. The navigationBar only has one button, 'Cancel', which I use to dismiss the view. Otherwise, the user must click on an image an perform another modal segue to a different view. This view has no navigation bar, and has one button 'DONE', which I use to perform a modal segue back to the initial tabBarController.
Here's the problem: the page is added to the scrollView with no errors after I press 'DONE'. However, I believe I now have two instances of the same tabBarController floating around in memory. When I attempt to grab the views contained in the scrollView with a different button, it tells me that it is now empty (even though it was full during viewDidLoad and viewDidAppear).
How can I remove the initial tabBarController view or otherwise how can I segue back to the tabBarController that I have already allocated? Any help would be extremely appreciated! Thanks!
You shouldn't do a segue back to the original view controller. Rather, you should dismiss the current view controllers animated, and show your original tabBarController.
Inside the view you were segueing back from, add:
tabBarController *tabs = (tabBarController*)[[self presentingViewController]presentingViewController];
tabs.selectedViewController = [tabz.viewControllers objectAtIndex:0];
[[[self presentingViewController] presentingViewController] dismissViewControllerAnimated:YES completion:nil];
Then you will have the view A appear and still use the same allocation.
I've got a storyboard with view A that is inside a navigation controller. I dynamically add subView B to view A. Subview B has a table view, and the table view cell has a seque (push) to a detail view. When I click on the cell, the prepareForSegue method is called, but the detail view is never displayed. If I switch the seque to a modal, then the detail view gets displayed inside view A, where subView B was.
What I want to happen is the detail view gets pushed onto the navigation controller and when the user hits back on the detail view it goes back to view A, with the subview B embedded.
Below is the code I use for adding the subview:
if(!self.homeViewController){
self.homeViewController = [self.storyboardinstantiateViewControllerWithIdentifier:#"HomeView"];
}
if(self.currentViewController != self.homeViewController)
{
[self.view insertSubview:self.homeViewController.view belowSubview:self.tabBar];
[self.currentViewController removeFromParentViewController];
}
self.currentViewController = self.homeViewController;
Without seeing your code (and storyboard) this may be hard to diagnose. I have found, however, that sometimes it's a chore to get segues to work properly with dynamically loaded content. In some cases I have found that using the pushViewController:animated: and popViewController:animated methods of the UINavigationController can be a better approach. You should be able to access the UINavigationController by through UIViewcontroller.navigationController.
i have two views say A & B. Both are the subclass of UIViewController class..View A is not a Table View but it is a scroll enabled view as it is more than the iphone dimensions 320*460. View B is not a scroll View. I am calling view B while clicking some button in View A like,
-(IBAction)bt:id(Sender)
{
B *mB=[[B alloc]initWithNib:#"B" bundle:nil];
[self.view addSubView:mB.view];
}
the problem is, As View A is larger, therefore when B is loaded over View A, even View A is partially visible in View B.please help me in overcome this problem??
The problem is you are adding view B to View A Subview and View A is in the scroll View so you need create a separate UIView Outlet and UIView in Interface Builder smallViewB the View A whatever size you need to display View B.
Then Add subview to View Outlet you created Above .
Please let me know if the problem persisting.
#interface ViewController A:UIViewController
#property(nonautomic,retain)IBOutlet UIView *smallViewB;
#implementation ViewController A
#synthesize smallViewB; //Make connection smallViewB in Interface Builder.
-(IBAction)bt:id(Sender)
{
B *mB=[[B alloc]initWithNib:#"B" bundle:nil];
[self.smallViewB addSubView:mB.view];
}
Before Adding view B to Main view remove the view A from its superview.
in .h take two objects
ViewA *aObject;
ViewB *bObject;
In View DidLoad create tow objects of View A and View B like this way
aObject=[[ViewA alloc]initWithNibName:#"ViewA" bundle:nil];
bObject=[[ViewB alloc]initWithNibName:#"ViewB" bundle:nil];
[self.view addSubView:aObject.view];
When You want to add View B add this code
[aObject.view removeFromSuperView];
[self.view addSubView:bObject.view];
Similarly IN Back Button action you can add code like
[bObject.view removeFromSuperView];
[self.view addSubView:aObject.view];
Try this code of snippets in your application I hope it will helps you. It wont lost your previous values of calss
Try adding this in you -(IBAction)bt:(id)Sender
ViewA.your_scroll_view.scrollEnabled=NO;
This might be what you wanted to do, if i understood it right.
Thanks for the suggestions but I have founda different solution to my problem.
When adding another view i.e. View B over Scroll View A, I reset the scroll view dimensions of A accordingly so that it is not visible. Also, when I press the Back button in View B, I again set the scroll View dimensions of View A to its previous value. Also, I made View A the delegate of View B since on pressing Back Button in B, I need to call a function which is defined in View A and is a part of View B protocol.
I have a Storyboard with three views A, B and C (and more). From view B, the user can go back to view A by tapping the left button bar item that's automatically created. I've changed the label on this to "Cancel" by setting the Back Button property of A's navigation item.
C should have the same Cancel button, but it doesn't make sense to go back to view B; rather it should jump back to A. I know how to do this programatically but where do I put the code so it's triggered when C's Cancel button is tapped?
I found this way simplest, just put index:
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
I think you cannot override the back button function. What I do in those cases, is create a left bar item and on it's function decide which navigationController view to send the user to.
I do that by using:
[self.navigationController viewControllers] objectAtIndex:1];
Index 1 will be the first view after the root viewController, if A is your rootView, you can also use:
[self.navigationController popToRootViewControllerAnimated:YES];
If you want to cancel an action from B or C and go back to A it may make more sense to present the view controllers modally.
From the iOS human interface guidelines:
A modal view generally displays a button that completes the task and dismisses the view, and a Cancel button users can tap to abandon the task.
Use a modal view when you need to offer the ability to accomplish a self-contained task related to your application’s primary function. A modal view is especially appropriate for a multistep subtask that requires UI elements that don’t belong in the main application user interface all the time.
Instead of pushing C, use the replace option in the segue so that it will do this automatically for you.
Another option: if you put the following into B, it will remove it from the stack when C is presented. Then the stack looks like [A,C] so back will go straight to A.
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
// remove this view controller from the stack
if let nav = self.navigationController {
let vcs = nav.viewControllers.filter {(vc) in
return (vc as? MyViewController) == nil
}
self.navigationController?.setViewControllers(vcs, animated: false)
}
}