example if there is a method addLabel:
- (void)addLabel {
for (NSInteger i = 0; i < 5; i ++) {
UILabel *label = [[UILabel alloc] init];
[label setText:#"label"];
[[self view] addSubView:label];
[label release];
}
}
and the method is called whenever a button is fired.
Does it need to remove all the label from the subviews first (removeFromSuperView:) before addSubview again?
First, you have to give some coordinate to UILabel. So that, it can display at proper place.
You can use following line for that:
UILabel *lblTaskTitle = [[UILabel alloc] initWithFrame:CGRectMake(45.0, 5, 200.0, 35.0)];
Another thing is that, it will be better if you remove other label. (It's not necessary, but it's good practice).
You can do it in following way:
UILabel *lbl = nil;
NSArray *Arraylbl = [self.view subviews];
for (lbl in Arraylbl){
if ([lbl isKindOfClass:[UILabel class]]){
[lbl removeFromSuperview];
}
}
Hope it will be fine for you.
Let me know in case of any difficulty.
Yes you have to remove all the previous labels from super view otherwise they all will be added above the previous existing labels, so the new labels would not be understandable.
Related
i have nsmutablearray in which i saved some character means alphabets now what i want is
to display these objects as subview on screen. and i did it easily..and em doing this through loop.. i am accessing arrays object one by one by which i can add these as subview but now em unable to remove these from super view.
I want to remove these labels. how can i do that?
UILabel *myLabel;
UIImageView *image;
for (int j = 0; j<[intValues count];j++) {
image = [allGridImages objectAtIndex:j];
image.userInteractionEnabled=NO;
image.multipleTouchEnabled=NO;
image.image= [UIImage imageNamed:#"box-1.png"];
title = [allGridBoxesTitle objectAtIndex:j];
myLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 1, 45, 45)];
myLabel.text = [allGridBoxesTitle objectAtIndex:j];
myLabel.textColor = [UIColor grayColor];
myLabel.font = [UIFont boldSystemFontOfSize:26.0f];
myLabel.backgroundColor = [UIColor clearColor];
[image addSubview:myLabel];
Try this method
- (void)removeAllLabels
{
for (UIView *view in self.view.subviews)
{
if ([view isKindOfClass:[UILabel class]])
{
[view removeFromSuperview];
}
}
}
You could do this before adding the new label:
[image.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
This will instruct any subviews to remove themselves.
However, this depends on the fact that a UIImageView doesn't have any subviews in the current version of iOS, which may not always be true. It'd be better to actually keep track of these labels and specifically remove them when you're finished with them, or even reuse them instead of making new ones every time.
i am a junior programmer
I face a problem of some of the subview in the program not shown ,
don't know if it is the addsubview order problem or the others .
hope if anyone can provide a suggestion or solution .thanks all
for (int i = 0; i < NUM_DISHES; i++) {
UIImageView* img_steps = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"%d.jpg", i]]];
//IMPORTANT: The i*W_IPAD means that 1st 0*1024 , 1*1024 , 2*1024.............and so on
[img_steps setFrame:CGRectMake(W_IPAD, 0, W_IPAD , H_UPFR)];
UIImageView* imageset = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[ary_img objectAtIndex:i]]];
[imageset setFrame:CGRectMake(89, 9, H_INGREPHOTO, W_INGREPHOTO)];
[ary_image addObject:imageset];
//ingredient amount section
UILabel* lbl_amt = [[UILabel alloc] initWithFrame:CGRectMake(128, 177, 190, 33)];
[lbl_amt setText:[ary_amount objectAtIndex:i]];
[lbl_amt setFont:[UIFont systemFontOfSize:25]];
[lbl_amt setTextColor:[UIColor blackColor]];
[lbl_amt setBackgroundColor:[UIColor clearColor]];
[ary_amt addObject:lbl_amt];
//method section
UILabel* lbl_method = [[UILabel alloc] initWithFrame:CGRectMake(596, 93, 130, 32)];
[lbl_method setText:[ary_meth objectAtIndex:i]];
[lbl_method setBackgroundColor:[UIColor clearColor]];
[lbl_method setFont:[UIFont systemFontOfSize:30]];
[lbl_method setTextColor:[UIColor blackColor]];
[ary_method addObject:lbl_method];
//alpha bar step number step number section
UILabel* lbl_numberstep = [[UILabel alloc] initWithFrame:CGRectMake(90 + (130 * i), 5, W_NUMBERSTEP, H_NUMBERSTEP)];
[lbl_numberstep setText:[NSString stringWithFormat:#"%d",i + 1]];
[lbl_numberstep setFont:[UIFont systemFontOfSize:20]];
[lbl_numberstep setBackgroundColor:[UIColor clearColor]];
[lbl_numberstep setTextColor:[UIColor blackColor]];
[self.view addSubview:img_steps];
[alpha_bar addSubview:lbl_numberstep];
[alphaframe addSubview:[ary_method objectAtIndex:i]];
[alphaframe addSubview:[ary_amt objectAtIndex:i]];
[alphaframe addSubview:[ary_image objectAtIndex:i]];
}
// Section --- Add Subview
[self.view addSubview:background];
[background addSubview:main_view];
[main_view addSubview:alpha_bar];
[main_view addSubview:alphaframe];
[main_view addSubview:but_transit_to_a]; //can add to the main_view
[main_view addSubview:left_buttom];
[main_view addSubview:right_buttom];
[alpha_bar addSubview:bar];
[alpha_bar addSubview:lbl_lastnum];
[alphaframe addSubview:but_transit_to_c];
}
return self;
}
To bring the subview to front you can use [yourMainView bringSubviewToFront:yoursubview]. If your subview isn't showing then, check that you've properly set up the subview's frame and that hidden = NO.
The view.subviews array holds the bottom-most view in index zero, and holds views in an order relating to their "z-index". So [myView.subviews lastObject]; will always give the view in front of all other views and [myView.subviews objectAtIndex:0]; will have the view below all views in that array.
From the UIView docs - subviews property:
You can use this property to retrieve the subviews associated with
your custom view hierarchies. The order of the subviews in the array
reflects their visible order on the screen, with the view at index 0
being the backmost view. For complex views declared in UIKit and other
system frameworks, any subviews of the view are generally considered
private and subject to change at any time. Therefore, you should not
attempt to retrieve or modify subviews for these types of
system-supplied views. If you do, your code may break during a future
system update.
i am working on one application in which i have added 5 labels dynamically in a function.when i recall the same function the labels are overridden on the previously created labels in spite of releasing the labels on each creation.
for(int i = 1; i < [array count]; i++)
{
CGRect lblframe = CGRectMake(count, ycord, width, height);
UILabel *label = [[UILabel alloc] initWithFrame:lblframe];
label.backgroundColor = [UIColor blackColor];
label.font = [UIFont systemFontOfSize:17];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor colorWithRed:(188/255.f) green:(149/255.f) blue:(88/255.f) alpha:1.0];;
label.text = [arr objectAtIndex:i];
count = count + xcord;
[subcatScroll addSubview:label];
[label release];
}
Write below code before for loop to get your requirement:
for (id object in [subcatScroll subviews]) {
[object removeFromSuperview];
}
I'm not sure I completely follow, so correct me if I'm misunderstanding.
Every time you call this function, you are adding a number of new labels. So if you call this function the second time, assuming 'count', 'ycord', 'width', and 'height' correspond with the values that the first call had, you are obviously adding a second group of labels in the same place as the first ones which are now directly on top of one another. You are not "overriding" the old labels, you are placing a second group directly ontop of the old ones.
Calling "release" on each label, only means you are decreasing the retainCount by 1. This number is used for memory management only. This means if you now remove the labels from the view the memory is released.
CGRect lblframe = CGRectMake(10.0, ycord, 200.0, 20.0);
UILabel *label = [[UILabel alloc] initWithFrame:lblframe];
NSLog(#"retainCount of label: %d", [label reatinCount]); // will print "1" since you called alloc
[self.view addSubview:label];
NSLog(#"retainCount of label: %d", [label reatinCount]); // will print "2" since adding to subview increases retaincount by one
[label release];
NSLog(#"retainCount of label: %d", [label reatinCount]); // will print "1" since you released
[label removeFromSuperview]; // will decrease retainCount of label to "0" and therefore free the memory
so say you wanted to remove the previously created labels from the view, you would have to do so. Either keep a reference to each of them and call "removeFromSuperview" on each of them.
If the only thing in the view where you're adding the labels, you can also just remove every subview that was added to it like so:
// remove old labels
for (UILabel *aLabel in [self.view subviews]) [aLabel removeFromSuperview];
NSArray *myArray = [NSArray arrayWithObjects:#"I", #"II", #"III", #"IV", nil];
for (int i=0; i<[myArray count]; i++) {
float ycord = i*40.0;
CGRect lblframe = CGRectMake(10.0, ycord, 200.0, 20.0);
UILabel *label = [[UILabel alloc] initWithFrame:lblframe];
label.backgroundColor = [UIColor blackColor];
label.font = [UIFont systemFontOfSize:17];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor colorWithRed:(188/255.f) green:(149/255.f) blue:(88/255.f) alpha:1.0];;
label.text = [myArray objectAtIndex:i];
[self.view addSubview:label];
[label release];
}
I hope this helped, but providing further info on what you're trying to do may make it easier to help you.
I'm creating a rate-a-fish application. When the user rates the fish, I want to display a little box which says "Average rating: * " with stars.
I have achieved something similar in cells for a table, but can't seem to get it to work in a normal view (I run the following code and nothing appears in the view):
-(void)displayAvg:(NSInteger)avg{
UILabel *text = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 90, 20)];
text.text = #"Average Rating:";
UIView *wrapper = [[UIView alloc]initWithFrame:CGRectMake(100, 200, 100, 30)];
wrapper.layer.cornerRadius = 8;
wrapper.backgroundColor = [UIColor whiteColor];
[wrapper addSubview:text];
[text release];
UIImageView *star;
NSInteger ratingI = avg;
for(int i = 0; i<ratingI; i++) {
star = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"little_star.png"]];
star.frame = CGRectMake(50 + (i * 16), 0, 16, 16);
[wrapper addSubview:star];
[star release];
}
[self.view addSubview:wrapper];
[self.view bringSubviewToFront:wrapper];
NSLog(#"Sleeping...");
[NSThread sleepForTimeInterval:3];
[wrapper removeFromSuperview];
[wrapper release];
}
I tried this code The problem is with the following line
[NSThread sleepForTimeInterval:3];
So instead of this line, you write a new method and call it with 'wrapper' as argument to remove the wrapper view.
[self performSelector:#selector(removeWrapper:) withObject:wrapper afterDelay:3];
implement the method
-(void)removeWrapper:(id)sender
{
UIView *wrapper = sender;
[wrapper removeFromSuperview];
[wrapper release];
}
This isn't answer to your question but I think it will be better to add timer that will fire in 3 seconds and then remove the window; you will not block the thread this way; Have you tried to add just simple sub view at first, i.e. wrapper with no other code? does it appear then? Or actually as I rethink the problem it might be the answer to your question - blocking thread this way might be the cause the window never get displayed. So far I know UI will be updated after thread returns to the run-loop.
I am creating a view like this:
UILabel *qty = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
qty.backgroundColor = [UIColor whiteColor];
qty.text =[NSString stringWithFormat:#" Qty: %#", currentQty];
qty.alpha = 0.5;
[qty setTag:999];
[self.view addSubview:qty];
[qty release];
This can happen multiple times in this view controller so before I create a new view like this I want to remove any that might exist with this tag, I am trying this:
UIView *removeView = [self.view viewWithTag:999];
[removeView removeFromSuperview];
This is not working for some reason, anyone see my problem here?
I guess i could loop through all the views and check the tag but would rather have a more elegant and direct solution.
Is the issue that you're possibly only removing one view of several? Try this:
UIView *removeView;
while((removeView = [self.view viewWithTag:999]) != nil) {
[removeView removeFromSuperview];
}
If there's only one view that's getting created/tagged/removed, you also might consider just adding a property to track that view, and writing:
[self.subView removeFromSuperview];
self.subView = qty;