removing some view from a view controller - iphone

I want to remove the current subview (added atIndex:0) from my root view controller and insert a new view in its place.
Currently I can only find code snippets that show unloading a view using removeFromSuperView, which requires you to know what viewcontrollers view is currently loaded.
The only other thing to note is that I have another subview inserted in the rootcontrollers view which i dont want unloaded. So code that removes any and all subviews is not adequate
Thanks,
m
if(self.firstscr == nil)
{
firstscreen *f = [[firstscreen alloc] initWithNibName:#"firstscreenview" bundle:nil];
self.firstscr = f;
[f release];
}
///This is my attempt at getting to the currently loaded view :P
[[self.view subviews atIndex:0].view removeFromSuperView];
[self.view insertSubview:firstscr.view atIndex:0];

Here is how to do it (i figured it out, Yey me!)
if(self.firstscr == nil)
{
firstscreen *f = [[firstscreen alloc] initWithNibName:#"firstscreenview" bundle:nil];
self.firstscr = f;
[f release];
}
//Remove whatever view is currently loaded at index 0, this index is only to be used by "page" views
UIView *v = [self.view.subviews objectAtIndex:0];
[v removeFromSuperview];
[self.view insertSubview:firstscr.view atIndex:0];

Related

EXC_BAD_ACCESS when dismissing modalViewController iOS5

I've been scratching my head for a long time now, trying to solve this problem. I've searched StackOverflow, and have found people asking for something that resembles my problem like this question and this question, but none of the answers given have helped me.
To explain the problem in detail:
I've used Apple's Paging example to enable paging between view controllers
The View hierachy is as follows: UIWindow -> UIScrollView (MainController) -> UIViewControllers.
I use this code to create a delegate to the Viewcontroller containing the UISCrollview:
if(page == 0)
{
ContractsViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *) controller == [NSNull null])
{
controller = [[ContractsViewController alloc] initWithNibName:#"ContractsView" bundle:nil];
controller.delegate = self;
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
controller.view.tag = 0;
[scrollView addSubview:controller.view];
}
}
The problem then occurs, when I try to present a modalviewcontroller from my ViewController inside the scrollview using the delegate. It works a few times, but then gives me a EXC_BAD_ACCESS. I've also tried posting a notification, and creating a listener in the MainController, to present it that way, but still the same problem.
When testing in iOS 4.3 everything works like a charm, but in iOS5 I get the issue.
I hope someone can help me get rid of this issue.
Thank you in advance.
As a start thank you for all your answers! I've finally found the solution to the problem.
As mentioned in my question, I used Apple's Pagecontrol sample as a template for my project. This template has a rootViewController which has an XIB with a window containing an UIScrollview and a Pagecontrol.
The problem happened, when I was trying to present the ModalView from a UIViewController inside the scrollview. I wanted to use the delegate, to present it through the rootViewController, but found out that it was using the UIScrollview to present it.
The UIScrollView object was apperently not retained, so after a couple of dismisses I hit the EXC_BAD_ACCESS.
I then figured, that i needed an UIView in the rootViewController, and placed it in the bottom viewhierachy in the XIB, and connected it with the view of the rootViewController. After I did that, I could use [delegate present..] and [delegate dismiss..] in the UIViewController without the EXC_BAD_ACCESS.
Yay! :)
I suggest removing your [controller release]; and adding an autorelease: controller = [[[ContractsViewController alloc] initWithNibName:#"ContractsView" bundle:nil] autorelease];
You don't own controller when it's returned from objectAtIndex:, so that way you could have the same behavior for both controllers, no releases.
I think I see your problem.. in the first if you release controller object and then you try to use it in the second if loop because of which you recieve this. release the controller object after both the if loops have passed.
EDIT:
try this code instead..
if(page == 0)
{
ContractsViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *) controller == [NSNull null])
{
controller = [[[ContractsViewController alloc] initWithNibName:#"ContractsView" bundle:nil]autorelease];
controller.delegate = self;
[viewControllers replaceObjectAtIndex:page withObject:controller];
}
// add the controller's view to the scroll view
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
controller.view.tag = 0;
[scrollView addSubview:controller.view];
}
}
Try running the code with NSZombiesEnabled.
My guess is that the viewControllers object is either never initialised or is being released prematurely.
Also, there's this if (page == 0) wierdness:
if(page == 0) // <== only the first page ever gets the init code calling
{
ContractsViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *) controller == [NSNull null])
{
// ** SNIP **
[viewControllers replaceObjectAtIndex:page // <<=== always 0
withObject:controller];
[controller release];
}
// ** SNIP **
}

Remove subView from View?

I have 2 Views, each View have a ViewController.
I opened the first view early in TabController.
Then (when a line in a table is clicked) I use this to add my subview:
ENSListViewController *vc = [ENSListViewController alloc];
vc.folder_id = 1;
vc.folder_type = #"an";
[vc initWithNibName:#"ENSListViewController" bundle:nil];
[self.view addSubview:vc.view];
[vc release];
In the second view I try to remove this view again, but it ends in a EXC_BAD_ACESS:
- (IBAction)backToFolderList:(id)sender
{
[self.view removeFromSuperview];
}
Where is my mistake?
You are releasing vc by [vc release]; hence it is not getting object of superview..
you have to release it in -dealloc method

Removing superview in objective-c

I'm looking through an example in the iPhone Beginning programming book and they have code to switch between two views when a button is pressed. Here's the first snippet from their example code:
if (self.yellowViewController.view.superview == nil)
{
if (self.yellowViewController == nil)
{
YellowViewController *yellowController =
[[YellowViewController alloc] initWithNibName:#"YellowView"
bundle:nil];
self.yellowViewController = yellowController;
[yellowController release];
}
[blueViewController.view removeFromSuperview];
[self.view insertSubview:yellowViewController.view atIndex:0];
}
else
{
if (self.blueViewController == nil)
{
BlueViewController *blueController =
[[BlueViewController alloc] initWithNibName:#"BlueView"
bundle:nil];
self.blueViewController = blueController;
[blueController release];
}
[yellowViewController.view removeFromSuperview];
[self.view insertSubview:blueViewController.view atIndex:0];
}
It does make sense to me, but the question I have is, how would you do this with a UISegmentControl that has four views. I know you can check for the selectedSegment and create that view when needed. But how would I know what the last view was in order to remove it from the superview beforing adding my new view as a subview? Thanks!
while creating each view either code or IB set tag value to segmentIndex.so u can get them later by that tag value.this is tricky and simple.
You could check to see which view is allocated or not nil and then remove.
if (yellowController) {
[yellowController.view removeFromSuperView];
[yellowController release];
}
You could go through your four views to determine which one is loaded and then remove the view.
For any UIView the frontmost subview is [[myView subviews] lastObject].

Two view App with root template view

Hi I was wanted to do Application witch have a root template view with a nice logo on top or something adn load other views just below
(here is what I have right now: Test App
)
But I have a little problem. If I'll remove a comment in file TestAppDelegate.m on line 58
//[currentView release];
Application will crash with bunch of errors when I try to switch views.
But if I comment this line Project analyzer is telling me that I have a potential leak
with currentView variable.
Can somebody spare some time and see in that code what I did wrong?
The problem is that you are only adding currentView.view as a subview so that is being retained elsewhere but currentView itself is not. This means that when you release it, it is consequently dealloc'd and its view will have difficulty working without it.
One solution would be to have currentView as an instance variable and create a property for it so that the memory mangement is done for you.
#property (nonatomic, retain) UIViewController *currentView;
and then replace a line like
currentView = [[First alloc] initWithNibName:#"First" bundle:nil];
with
self.currentView = [[First alloc] initWithNibName:#"First" bundle:nil];
This will release the old view controller before retaining the new one. Then lastly don't forget to release currentView in the dealloc method of the class.
I have a function and it looks like this:
- (void) switchView: (int) viewType {
for (UIView *view in [self.viewController.rootView subviews]) {
[view removeFromSuperview];
}
UIViewController *currentView = nil;
switch (viewType) {
case 1:
currentView = [[First alloc] initWithNibName:#"First" bundle:nil];
break;
case 2:
currentView = [[Second alloc] initWithNibName:#"Second" bundle:nil];
break;
}
[self.viewController.rootView addSubview: [currentView view]];
[self.window makeKeyAndVisible];
//[currentView release];
}

Navigating to another view controller without a navigation controller

As you guess am still a newbie, getting my head around iphone development.
I am just trying out basic view loading on demand, which i cant get to work
I have an app, with 2 view controllers, each view controller connected a different nib file.
I am trying to switch between view manually; there is no navigation control involved.
How can i manually push the second view to the first view?
self.navigationController pushViewController wont work since there is no navigation controller.
How else can I push the second view on top of the first view and destroy the first view; and ofcourse vice versa?
I have done this in the first view's button action:
SecondView *sv=[[SecondView alloc] initWithNibName:#"SecondView" bundle:nil];
[self.navigationController pushViewController:sv animated:YES];
obviously, it didn't work.
window addSubView didn't work either, because the first view controller is the root view controller (not sure i said that right). In other words, when i run the app, the first view is what I see with a button that is supposed to load the second view.
I have spent hours searching for a simple example, and I couldn't find any.
Any suggestions?
in the first view controller you need this:
- (IBAction)pushWithoutViewController:(id)selector {
NextNavigationController *page = [[NextNavigationController alloc] initWithNibName:NextNavigationController bundle:nil];
CGRect theFrame = page.view.frame;
theFrame.origin = CGPointMake(self.view.frame.size.width, 0);
page.view.frame = theFrame;
theFrame.origin = CGPointMake(0,0);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.8f];
page.view.frame = theFrame;
[UIView commitAnimations];
[self.view addSubview:page.view];
[page release];
}
and then link it to the button in nib. :)
try :
SecondView *sv=[[SecondView alloc] initWithNibName:#"SecondView" bundle:nil];
[self presentModalViewController:sv animated:YES];
IF you have first xib and you want to give navigation to another controller then you have to declare navigation in to appdelegate.m
write following code to app
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = navController;
then in ViewController.m
- (IBAction)NextButtonClicked:(id)sender
{
yourNextViewController *objyourNextViewController = [[yourNextViewController alloc] initWithNibName:#"yourNextViewController" bundle:nil];
[self.navigationController pushViewController:objStartUpViewController animated:TRUE];
}