- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
[[self model] setTransitioning:NO];
[[[[self view]subviews] objectAtIndex:0] removeFromSuperview];
}
How can I tell what kind of viewController controls the subview at index 0?
If it's a QuizViewController I need to call a function on it.
Thanks in advance.
Good answers. I don't believe I explained enough. This is a all in a view controller that is a view stack. The view controller adds and deletes views manually with an animated transition. I am not using a navigationController and cannot in this particular instance for other reasons.
Sometimes the views I add are simple UIImageViews. Sometimes they are QuizViews. The QuizViews have a QuizViewController because they need internal functionality. Here are the two functions I use to add the views.
- (void)loadQuiz:(NSInteger )quizNum
{
if([self quizViewController] != nil)
{
[self setQuizViewController:nil];
}
QuizViewController *quiz = [[QuizViewController alloc] initWithNibName:#"QuizViewController" bundle:nil];
[quiz setUp:quizNum];
[self setQuizViewController:quiz];
[quiz release];
[[self view] addSubview:[[self quizViewController]view]];
[self setSlide1:[[[self view] subviews] objectAtIndex:0]];
[self setSlide2:[[[self view] subviews] objectAtIndex:1]];
[[self slide1] setHidden:NO];
[[self slide2] setHidden:YES];
[self performTransition];
}
- (void)loadImage:(NSString *)slideImage
{
UIImage *tempImg = [UIImage imageWithContentsOfFile:[Utilities localPathForFileName:slideImage]];
UIImageView *temp = [[UIImageView alloc] initWithImage:tempImg];
[[self view] addSubview:temp];
[temp release];
//[topView release];
if ([[[self view]subviews] count] > 2) {
//add the 2nd subview
//[[[[self view]subviews] objectAtIndex:0] removeFromSuperview];
}
[self setSlide1:[[[self view] subviews] objectAtIndex:0]];
[self setSlide2:[[[self view] subviews] objectAtIndex:1]];
[[self slide1] setHidden:NO];
[[self slide2] setHidden:YES];
NSLog(#"%s %d",__FUNCTION__,[[[self view]subviews] count]);
[self performTransition];
}
So my question is still, in the animationDidStop function how do I detect if it's a quiz?
if ([[self view]subviews] objectAtIndex:0] isKindOfClass:CLASS(class))
...
or isMemberofClass
From memory so you'll have to test it out...
You can also set a tag on the view when you create it, then look for the view when you retrieve it.
someUIView.tag=99;
then
if ( [[self view]subviews] objectAtIndex:0].tag == 99 )
...
Cheers
You maintain one UIViewController (for e.g. UIViewController *currentViewController) object for keeping the track of current view controller.
Now before pushing to the viewcontroller which according to my understanding gets pushed by more than one view controller,you set the currentViewController with the viewController from which you are pushing.
So if you are in QuizViewController and pushing to viewController which controlls subviews,you first set currentController of it and then push it.
subViewController.currentController = self;
[self.navigationController pushViewController:subViewController animated:YES];
Views don't inherently have view controllers attached to them, so the way your question is worded doesn't quite make sense. If what you're doing is having a UIView subclass, say QuizView, as a subview and need to know when that is being removed and act on it, then the code would look like this;
-(void) animationDidStop:(CAAnimation*)theAnimation finished:(BOOL)flag
{
[[self model] setTransitioning:NO];
UIView *subview = [self.view.subviews objectAtIndex:0];
if([subview isKindOfClass:[QuizView class]])
{
[(QuizView*)subview yourFunction];
}
[subview removeFromSuperview];
}
If you mean something different and you can provide some code I might be able to help more, but like I said your original question isn't quite clear to me if this isn't what you mean ;)
Related
I have a problem in clearing my view, For a particular case I have been adding user names as label into my view, I may have multiple user based on situation, now my problem is, For one case I want to clear the view without popping it, I am not sure how to remove those added labels, I have an idea I can set tag for each label, and I can clear using that later. Any other efficient way is there in this particular case.
Hope my question is clear thanks.
use
for (UIView* view in self.view.subviews) {
if(view isKindOfClass:[UILabel class]) {
//do whatever you want to do
}
}
You can remove all subviews like this:
for (UIView *subView in [view subviews])
[subView removeFromSuperview];
Or if you want to access a particular view with tag value of n,
UIView *subview = [view viewWithTag:n]
You can do in the following way
for (UIView *view in [self.view subviews])
{
if ([view isKindOfClass:[UILabel class]])
{
[view removeFromSuperview];
}
}
Hope you are asking about this.
[labelName removeFromSuperview];
use this :
for(id viewSub in self.view.subviews)
{
[viewSub removeFromSuperview];
}
this will remove all subviews of View
Try this:
for (UIView *v in [self.relatedView subviews])
{
[v removeFromSuperview];
}
Call below method and pass the "UIWebView" object as argument:
+(void)removeAllSubViews:(id)pObj
{
NSArray *Array = [pObj subviews];
for(int index = 0; index < [Array count]; index++)
{
[[Array objectAtIndex:index] removeFromSuperview];
}
}
You can also check object like this if you want for any particular object:
if(view isKindOfClass:[UILabel class]) {
//do whatever you want to do
}
Cheers!
I am currently at topViewController while a UIView is added to my rootViewController. Is there any way that I can remove all UIViews before going to rootViewController via popToRootViewContoller?
In Going back action,type following code:
for (UIView *subview in self.view.subviews) {
[subview removeFromSuperview];
}
And then type popToRootViewContoller.
Add this in viewWillAppear: method of YourViewController
for (UIView *view in self.view.subviews) {
[view removeFromSuperview];
}
Hope it helps you
In viewWillDisappear you can do this task, when you are leaving your rootViewController then this method will call , so you can remove your view at this point.
-(void)viewWillDisappear:(BOOL)animated
{
for (UIView *view in [self.view subviews]) {
[view removeFromSuperview];
}
}
Try this:
-(void)viewWillAppear:(BOOL)animated
{
NSArray *subviews = [self.view subviews];
for (UIView *subview in subviews) {
[subview removeFromSuperview];
}
}
[yourView removeFromSuperView]
but added subviews willnot be there when you pop a UIViewController, so i don't think you need to do this
This is my first post and you are my last hope.
I have a list with images in my iPad app, if you select one, my class MyViewController which extends UIViewController is loaded and shown (by just setting window.rootViewController, by using UINavigationController, by presentModalViewController - tried everything, doesn't make any difference). It has a UIScrollView inside, which adds a big version of the image to the UIScrollView with this code:
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[[delegate getImageNames] objectAtIndex:(gameNr*2)]]];
tempImageView.frame = CGRectMake(0,0,tempImageView.frame.size.width/2,tempImageView.frame.size.height/2);
[self setMyImage:tempImageView];
[tempImageView release];
myScrollView.contentSize = CGSizeMake(myImage.frame.size.width, myImage.frame.size.height);
myScrollView.maximumZoomScale = 2.0;
myScrollView.minimumZoomScale = 1.0;
myScrollView.clipsToBounds = YES;
myScrollView.bounces = NO;
myScrollView.delegate = self;
[myScrollView addSubview: myImage];
myImage is a (nonatomic, retain) property of the type UIImageView inside my MyViewController.
After pressing a button and go back to the list of images, I release the reference to MyViewController and it's dealloc method is called like this:
- (void)dealloc
{
CFShow(#"dealloc!");
for(UIImageView *subview in [myScrollView subviews]) {
if(subview.frame.size.width > 20){
[subview removeFromSuperview];
[subview setImage:nil];
}
}
[myImage setImage:nil];
self.myScrollView = nil;
self.myImage = nil;
[myScrollView release];
[myImage release];
[super dealloc];
}
It works so far, but the problem is, that the memory of the images is not really deallocated this way. After opening and closing about 12 images, the app crashes with memory warning.
This is also confirmed by the report_memory method I got from here:
iOS Low Memory Crash, but very low memory usage
The dealloc method IS called, that's triple checked.
I checked the variables myImage and myScrollViewvia breakpoint in the debugger, they are set to 0x0 by those commands in the dealloc method. Why is the memory not freed????????
Thanks for any suggestion, I am working on this since three whole days, it's driving me crazy.
Replace this:
self.myScrollView = nil;
self.myImage = nil;
[myScrollView release];
[myImage release];
with this:
[myScrollView release];
self.myScrollView = nil;
self.myImage = nil;
And post code where you define property myScrollView and init it.
And you don't need loop for(UIImageView *subview in [myScrollView subviews]). When you will release myScrollView object it will automatically release all its subviews.
I wonder if someone could quickly help me with the following, do I need to add a [myTableView release]; after I call [view addSubview:[self myTableView]]; ? Initially I was thinking no, and running it through CLANG produced to memory warnings
Here is my thinking:
[self setMyTableView:tempTableView]; retainCount = (+1)
[view addSubview:[self myTableView]]; retainCount = (+2)
//[myTableView release]; << HERE retainCount = (+1)
-dealloc [myTableView release]; retainCount = ( 0)
.
#property (nonatomic, retain) UITableView *myTableView;
.
- (void)loadView {
NSLog(#"%s", __PRETTY_FUNCTION__);
[self setTitle:#"Location Data"];
CGRect viewFrame = CGRectMake(0, 20, 320, 460);
UIView *view = [[UIView alloc] initWithFrame:viewFrame];
CGRect tableFrame = CGRectMake(0, 0, 320, 416);
UITableView *tempTableView = [[UITableView alloc] initWithFrame:tableFrame];
[self setMyTableView:tempTableView];
[tempTableView release];
[view addSubview:[self myTableView]];
//[myTableView release]; << HERE
[[self myTableView] setDelegate:self];
[[self myTableView] setDataSource:self];
[self setView:view];
[view release];
}
.
- (void)dealloc {
[myTableView release];
[dataModel release];
[super dealloc];
}
EDIT: hmm maybe I don't as [view addSubview:[self myTableView]]; retains it and will release when done. Your right Carl, my bad. I was getting confused with: alloc, set, release, when this is simply the view taking ownership (and the responsibility to release that later)
You're right when you say that [view addSubview:[self myTableView]]; will retain your table view, but since it's the view who is retaining it, it's the view that is supposed to release it. And it will, when the view gets dealloc'ed. You only have to release what you retained yourself, i.e., you only have to release the table view once in your dealloc method.
Your method doesn't retain myTableView, so it shouldn't release it.
Im have a slight amount of trouble adding a new view to my scene, I have the code like this:
- (void) showMyDayView {
NSLog(#"My Day View was touched");
MyDayViewController *temp = [[MyDayViewController alloc] initWithNibName: #"MyDayView" bundle:nil];
self.myDayViewController = temp;
NSLog(#"superview: %#", [[self mainNavView] superview]);
[[self mainNavView] removeFromSuperview];
NSLog(#"after removal main: %#", [self mainNavView]);
NSLog(#"after removal view: %#", [self view]);
NSLog(#"after removal superview: %#", [[self view] superview]);
[[[self view] superview] addSubview: [self.myDayViewController view]];
[temp release];
}
And when I run this code, the console says "after removal superview: (null)"
so when I add the subView to the superview, nothing happens because the superview is null.
Any ideas?
Thanks
Mark
If you want to reuse a view that you are going to removeFromSuperview, you must retain it first. removeFromSuperview releases any view it is invoked on.
So...
[[self mainNavView] retain]
[[self mainNavView] removeFromSuperview];
And [self mainNavView] remains safe to use.