when I call removeFromSuperview from my view.m file( [self removeFromSuperview]; ), it seems working fine. but when I call that method from the view controller.m file([self.view removeFromSuperview]) it only returns error. I have no idea what is wrong about it.
I am guessing your view is one of the subviews in your controller's view. Calling [self.view removeFromSuperview] only tries to remove the controller's view from the parent view. This is probably not what you want to do. You need to find the child of self.view that is of your view's type ( or using a tag) and then remove it.
Without the exact code this is what you need to do.
Set the tag of the view that you want to be removed to 42 (myview.tag = 42 ) before/after adding it to the controllers view.
When you are ready to remove the view loop through the subviews of controllers view and if the subview's tag is 42 then do a removeFromSuperview on that view. So something like this
for (UIView *view in [self.view subviews] ) {
if (view.tag == 42 ) {
[view removeFromSuperview];
}
}
Related
I have a main UIViewController where most of the users' interaction happens. In the main ViewController there are three subviews. The user can load separate ViewControllers into the UIView subviews.
Each of the subviews that are loaded deal with data entry. In turn, firstResponders are called. I would like to be able to dismiss the firstRespnders through the main ViewController, maybe with a 'Done' button.
I was thinking I could add a method in each of the separate subviews with one name ex;
-(void) methodToResignResponders {}
Then, in the main ViewController call this method to the view that is currently open to the user. In turn resigning the responders that are active in the subview.
Further Information:
This is how I set up each view as a subview of the main ViewController:
UIViewController *calcVC;
//set up the view to be added depending on the name of the view that was passed
if ([viewName isEqualToString:#"Tax"]) {
calcVC= [[TAXViewController alloc]initWithNibName:#"TAXViewController" bundle:nil];
}else if ([viewName isEqualToString:#"Rent"]){
calcVC= [[RENTViewController alloc]initWithNibName:#"RENTViewController" bundle:nil];
}else //continues with more views...
//Then add it to the subview
[firstView addSubview:calcVC.view];
Not sure if I've got the gist of this, mostly because it sounds like you've already solved it yourself. :)
But, from what I can see the ViewController you are talking about is always an UIViewController instance named calcVC. If it is always this viewController's view you are referring to you can simply call [calcVC.view resignFirstResponder];
You can make a basic protocol that all of your sub-view controllers implement that has does everything you need (resign first responder and anything else).
Not sure if this answers your question but you can loop through all the subviews and call it if it exists as follows:
for (UIView *subview in [self.view subviews]) {
if ([subview respondsToSelector:#selector(resignFirstResponder)]) {
[subview resignFirstResponder];
}
}
i like to create a second starting screen in my app.
My Idea is to use the default.png and load an UIView with an fullscreen UIImageView inside.
In viewDidLoad i thought about placing a sleep option and after this load the real app screen.
But also when my function is called in viewDidLoad, nothing happens.
Seems my superview is empty...
Here is a piece of code:
if (self._pdfview == nil)
{
pdfview *videc = [[pdfview alloc]
initWithNibName:#"pdfview" bundle:nil];
self._pdfview = videc;
[pdfview release];
}
// get the view that's currently showing
UIView *currentView = self.view;
// get the the underlying UIWindow, or the view containing the current view
UIView *theWindow = [currentView superview];
theWindow is empty after this line so that might be the reason why the other view is not loaded.
So my question, how do i create a second starting screen ?
Or three starting screens, like in games when i like to mention another company.
If I understand correctly, your point is that when your function above is executed from viewDidLoad of some controller, theWindow is nil, so your new view (startscreen) is not added to it.
A few observations:
if theWindow is nil, then self.view is the topmost UIView; you can try and replace it, or simply add your view to it:
UIView *currentView = self.view;
// get the the underlying UIWindow, or the view containing the current view
UIView *theWindow = [currentView superview];
UIView *newView = _pdfview.view;
if (theWindow) {
[currentView removeFromSuperview];
[theWindow addSubview:newView];
} else {
self.view = newView; //-- or: [self.view addSubview:newView];
}
if you want to get the UIWindow of your app (which seems what you are trying to do), you can do:
[UIApplication sharedApplication].keyWindow;
and from there you can either set the rootViewController (from iOS 4.0)
[UIApplication sharedApplication].keyWindow.rootViewController = ...;
or add newView as a subview to it:
[[UIApplication sharedApplication].keyWindow addSubview:newView];
in the second case, you should possibly remove all subviews previously added to the UIWindow. (Iterate on keyWindow.subviews and call removeFromSuperview).
OLD ANSWER:
I think that you should try and add your pdfview as a subview to the current view:
[currentView addSubview:videc];
or to what you call theWindow:
[theWindow addSubview:pvidec];
and, please, move the release statement after the `addSubview, otherwise the view will be deallocated immediately.
I have a UISegmentedController i have 3 UIViewControllers Like photos,frames,gallery.
I add those 3 Views in Superview Using 'addSubView'. In frames view i have added a subview that name as EditView. In EditView i have done some changes, i want to update these changes in frames view. But when am removing EditView from frames view any single method doesn't calling. Then how to update the changes from subview in superview. Tree: UISegmentedController -> Frames(Su) -> EditViews(Subview). Can any one help me..
I found the code to update something in superview from subview. Please use this code in your subview. It will call your superview viewWillAppear method. You can use another method instead of viewWillAppear. It works for me.
for (UIView* next = [self.view superview]; next; next = next.superview)
{
UIResponder* nextResponder = [next nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]])
{
[(UIViewController*)nextResponder viewWillAppear:YES];
}
}
-Yuva.M
You could access the super view of any UIView by using the superview property of UIView.
The below statement will be in your EditView.
FrameView* mySuperFrameView = (FrameView*)self.superview;
and the next statement could be calling the super view function.
[mySuperFrameView updateMySuperView];
updateMySuperView is the part of your superview.
Removing a view from its superview releases it.
Submit your changes before removing the editView from its superview. You could overwrite removeFromSuperview in your editView, and do your data manipulation before calling super removeFromSuperview.
Or your view controller could take data from the editView before removing it.
I have TabBarController in app, so all tab bar items are loading at same time,,
when I am update data, and coming back, then previous views are still there and new views are added above them
what should I do
my Coding is in ViewWillApear,
I haven't code in ViewDidLoad because I want to see data as I update them in database,
and ViewDidLoad is being called once, but ViewWillApear is being called everytime,
so everytime new views are added and previous are there,,,,
hope you understand what I mean,,,
You want the values displayed by those views or you want to update the views in all.
If you want to update only values, then do that in viewWillAppear: no need to create and add the whole views again. Its not good practice.
Create the views once only in loadView or viewDidLoad: method. and assign them values in viewWillAppear:
or else in your
-(void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self removeAllSubviews];
//OR
for(UIView * view in self.view.subviews)
{
[view removeFromSuperview];
view = nil;
}
}
In a view based app, I display a view and once the user is finished with that view, Done is clicked and the view is removed. However, that does not dealloc the view, which is what I want to do. What is the proper way to dealloc this type of view?
Currently, I'm nil'ing out the second view before it is called. That seems to work and the second view is reinitialized. However, isn't it more appropriate for the second view to destroy itself (nil itself after removeFromSuperview)?
In first view:
//show next view
aView = nil;
if(aView == nil)
{
aView = [[AView alloc] initWithNibName:#"aView" bundle:nil];
}
[self.view addSubview: aView.view];
Click Done in aView
[self.view removeFromSuperview];
The method removeFromSuperview will automatically release "aView.view", so you shouldn't release aView in the first view controller. I think you've declared AView *aView in head file, but you don't need to. You may declare the aView as a local variable like this:
// go to second view
SecViewController *sec = [[SecViewController alloc] initWithNibName:#"SecView" bundle:nil];
[self.view addSubview:sec.view];
// go back
[self.view removeFromSuperview];
Immediately after
[self.view addSubview: aView.view];
You should add:
[aView release];
Your subview has been retained by your view controller's view so can be release.
If you previously set your viewController to first responder status (like to respond to motion events) the responder chain will retain the controller. You must resign the first responder to destroy the controller completely.
[self resignFirstResponder];
[self.view removeFromSuperview];
both of the above answers are correct theory for how you should memory manage in objective c.
as per the dev documentation:
http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/removeFromSuperview
callling removeFromSuperview will actually call release FOR you, so you are okay, I think.