Access UIView after adding it to superview/as a subview - iphone

I have a variable sized array of UIImageViews that I'd like to add to my main View. So I loop through the array, adding each UIImageView to the scene as follows:
for (UIImageView *nextImageView in myImageArray]
[self.view addSubview:nextImageView];
(I also configure their frames individually but have left that out here)
However, I later want to remove these UIImageViews. But how can I access them? I'm aware of the tag property, and that I could tag each one as I add it, and then remove views of the same tag, however I'm also adding and removing other elements to the view which messes up the index, and it doesn't seem like a very foolproof solution.
I thought of having a single UIView property in my class, and adding the array of UIImageViews as subviews of this main view, like so:
for (UIImageView *nextImageView in myImageArray]
[holderView addSubview:nextImageView];
Then I can remove all the images by calling:
[holderView removeFromSuperview];
However, I'm not sure how to arrange the UIImageViews within the UIView. If I try to configure their frames individually, they don't appear. So at the minute they just draw over the top of each other. Ideally I'd like them to appear in a stack. Any ideas how I might do that?
Thanks :)

I believe you could iterate the array of UIImageViews and call removeFromSuperview
for (UIImageView *nextImageView in myImageArray]
[nextImageView removeFromSuperview];
Hope this helps.

Related

UIImageView layer order

I am having trouble understanding how layering is performed within Xcode. I have a .xib with a view, that view has 6 UIImageView 's which each contain a different image. I have created IBOutlets for each of these so I can change the image at runtime.
I now want to change the order the UIImageViews are drawn at runtime, so imageA at the back is now drawn on top of everything else. How can I change the layer order? I originally tried removing all the subviews and using [self.view insertSubview: atIndex: ] to see if I could change the draw order that way but my code crashes.
Can anyone tell me the correct method for doing this please?
Thanks in advanced,
Elliott
i guess you are looking for these UIView methods:
1:
exchangeSubviewAtIndex:withSubviewAtIndex:
Exchanges the subviews at the specified indices.
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2
2:
bringSubviewToFront:
Moves the specified subview so that it appears on top of its siblings.
- (void)bringSubviewToFront:(UIView *)view
3:
sendSubviewToBack:
Moves the specified subview so that it appears behind its siblings.
- (void)sendSubviewToBack:(UIView *)view
with these methods you can exchange the subviews order to get one UIView appear over one other in their superview... if that's what you were asking....
A crash may be because when you remove the image from its parent, its retain count goes to zero and is deallocated.
If you just want to swap two views, see - (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2 on UIView. If you want to do a more complicated exchange, you can remove and readd, just make sure you retain the view you remove (ARC notwithstanding).

UIImageView's startAnimating does remove itself when animation is finished?

animating with UIImageview takes the following steps
create autoreleased UIImageView
create array of image
assign the image array to UIImageView's animationImages property
set other properties
add UIImageView to a view as subview
startAnimating
I'm worried about memory leak.
Would the imageView get dealloc-ed as long as the UIImageView is autoreleased object?
It sounds like you want the image view to go away after the animation is complete. As it is, it will not. It will remain a subview. I'm not sure what it will look like when the animation is complete.
It's not a memory leak per-se, since the view still has a pointer to the image view, but if you repeat the above over and over again you will have less and less memory. You need to remove the image view from its parent view at some point.
Probably what you can do is create an animation using [UIView animateWithDuration:animations:completion:]. Give it a duration equal to the duration of your animated image. In the animations block do nothing. In the completion block remove the image view from its superview.
Or just do performSelectorAfterDelay to call something that removes the view. Not sure if one will better guarantee synchronization with the animation of the sequence of images.
You can try this:
Memory leaks debugging
I hope it will help ^^
You can be certain about the fact that the UIImageView will not be released as long as it is a part of the view hierarchy.
Also, if you allocated the NSArray in step 2, you should release it after step 3. The rest looks good.
If you just want to remove the imageview from superview after the animation is complete, use the following two lines:
[UIImageView setAnimationDelegate:self];
[UIImageView setAnimationDidStopSelector:#selector(removeFromSuperview)];

iPhone dev - I want a custom UIView that is made up of many subviews. In what method should I add the subviews?

Basically I want to have a custom UIView that has a bunch of buttons in it. Should I just add the buttons to the view inside initWithFrame? I also would like to set up all their locations in the view at the same time. Is there a customary place where all this would be done? I'm guessing I shouldn't do anything in drawRect since I'm not making any custom drawings, just adding buttons as subviews. Thanks.
initWithFrame: is a good place to add the buttons.
If the buttons' frame depends on the parent view's size, you should set the frame of the buttons in the parent view's layoutSubviews method. Otherwise you can just specify the buttons' autoresizingMask when you add the buttons.
You can't set up all their locations "at the same time", but if you call many addSubview: sequentially you don't see even that were added one at a time.
You do not always need to subclass UIView(if it is not particularly complex), you can create it at run time, add the components that you want with initWithFrame: and show it; otherwise you can subclass UIView just to create the layout (rounded border, gradient color, etc), initialize it from your class and add the components. If you have some problem, show us more details about your problem.

UIScrollView doesn't bounce

I have a UIScrollView contained within a custom UIView with a content size larger than the ScrollView's frame.
I am able to drag scroll as I expect, but the thing doesn't give me the rubber banding effect that you get with the UITableView or UIWebView. It just stops when you get to one of the extremes.
I have set bounce = YES, is there something else I'm supposed to do?
I read the docs, and they say I have to implement the delegate. I did that.
They also say I should change the zoom levels, but I don't want the user to actually be able to zoom so I haven't set these.
For anyone that finds this thread later, if you are subclassing UIView and re-setting the UIScrollView's frame on every layoutSubviews, that is the problem - it cancels the bounce:
http://openradar.appspot.com/8045239
You should do something similar to this:
- (void)layoutSubviews;
{
[super layoutSubviews];
CGRect frame = [self calculateScrollViewFrame];
if (!CGRectEqualToRect(frame, self.scrollView.frame))
self.scrollView.frame = frame;
}
I had the same problem, on a UIScrollView that wasn't all filled up (but I still wanted it to bounce). Just setted:
scroll.alwaysBounceVertical/Horizontal = YES;
And it worked as expected
It turns out that keeping the UIScrollView within my custom UIView was causing the trouble.
Once I switched my custom UIView to instead inherit from UIScrollView, then the bouncing started working.
That is interesting... Is there a lot going on while the user scrolls the scroll view? Maybe that could cause the problem. The iPhone can multitask, but not too much. Can I see your entire code having to do with the scroll view?

Sending view to back

When I try to send a view to the back, it hides some of the buttons and labels in my view controller. The view I am sending to the back is a UIImageView. Does anyone have an opinion of what might be the problem?
Here is the code I am using:
UIImage *image = [UIImage imageNamed: #"background.jpg"];
UIImageView *backImage = [[UIImageView alloc] initWithImage: image];
[self.view addSubview: backImage];
[self.view sendSubviewToBack: backImage];
Then, when I am adding controls to self.view, they does not always show
I managed to get it roght by moving my code from init to loadView. I don't understand why that should make a difference, but hey.. it works!
If you are using UIView's sendSubviewToBack: or a similar message, you probably have your buttons inserted in the hierarchy under the UIImageView. When a view moves in the hierarchy, all of its subviews move with it.
To fix this, you need to add your controls as subviews of the same view (possibly the UIWindow) you added the UIImageView to initially.
Without seeing your code, it's very difficult to be more precise.
By not having to add it programmatically and adjust the views, much easier to layer each one in the interface builder. Make sure the image view, if this is set as the background, make sure it is the first to be listed.
Agreed. Not quite sure by what you mean by "send to the back" but here's a guess...
If you are adjusting the layering within your main view, be sure you are not sending a view "to the back" (changing it's layer) that has number of subviews... or else they would all go to the back (their layering would change) at the same time.
If this is totally not what you meant, just let me know, and I'll delete this answer.