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)];
Related
I've got a UIView with a UILabel on top. I have the UILabel's content mode set to 'UIContentModeLeft'. As expected, when I animate the frame of the UIView to be smaller than the original size, the label 'jumps' to the final frame without animating nicely.
As far as I can see, UIContentModeRedraw does not force 'drawRect' to be called on every 'animated frame'. I've tried using a custom CALayer as well but can't seem to cause the frame to resize smoothly.
Is there any way to do this? The animation as it stands is extremely glitchy. UIContentModes are not useful and I can't use a frame for contentStretch as well as none of the edges of the label can be stretched. What I really need is a 'refresh' of the label every time the parent view resizes.
There's no way of doing this unfortunately, so I've learnt. The only other way is to actually run a timer that updates the frame every time it's invoked. This results in a very jerky animation given a resize of a complex view is time consuming. I ended up achieving the same thing with some pre-rendered onscreen elements and a whole lotta 'magical effects' behind the scene.
I'm doing UIView animation on individual subviews that have a number of sibling views that I don't want affected by the single-view animation. However layoutSubviews is being called on the containing superview when I do the animation, causing the other siblings to be rearranged as well.
(I should explain that I'm doing initial subview layout in the parent view's layoutSubviews method; I only want it to be called the first time I'm setting up the subviews, not when I'm animating them individually later on.)
Why is the parent view's layoutSubviews method being called when animating its subviews?
I can imagine "sorting a grid of icons", you'll just have to animate one icon and the rest works automatically.
On the other side: What autoresizing masks do you have set for the view you're animating? Perhaps it has to do with that. What type of UIView are you animating? Perhaps it changes shape and thus calls [self.superview setNeedsLayout] to tell the superview that it changed shape.
Other idea: Has your superview "autoresizedSubviews" set?
I've found that even setting transformations on the layers of a view can trigger the view's setLayoutSubviews. It took me by surprise too, but maybe just because I don't need the behavior right now. It might sometimes become handy, I guess…
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.
I'm making an OpenGL ES application and I am trying to work out how to incorporate parts of the UIKit GUI over the view with the OpenGL ES working on it.
In the init method of the EAGLView class I have this to setup the UITextField:
add_name_field = [[UITextField alloc] initWithFrame: CGRectMake(10, 10, [UIScreen mainScreen].bounds.size.width, 50)];
Somewhere in the drawRect method where everything is rendered and processed for the game I have:
[add_name_field becomeFirstResponder];
[self insertSubview: add_name_field atIndex:0];
I can confirm this code is called because I used NSLog to test that but when it is run the text field does not show over the game's OpenGL view. If I put the code in the init method, the text field shows properly with the keyboard at te beginning of the game.
So how do I get it to work in the drawRect method?
Thank you for any answer. I will write some code for the delegate in the meantime.
THank you for all the other answers but I found the solution.
It was a simple solution. I simply moved the addSubView method to the initialisation of the EAGLView class. The keyboard wont show until I make the text field the first responder. When I'm finished with it, I can simply clear the text and make the EAGLView class the first responder again and that hides it all again.
This way I can simply use the keyboard to get text input for my game, displaying text when typing and hiding it afterwards.
I assume you're in a UIViewController subclass, with the code above? If so, then instead of
[self insertSubview: add_name_field atIndex:0];
do:
[self.view addSubview:add_name_field];
The important part is, you're calling this method on self.view rather than self. Adding subviews is a VIEW function, not a View CONTROLLER function.
insertSubview:atIndex: ought to work too (if called on the right object), but addSubview: will stick it on top of the view no matter what else is there, so it's a bit cleaner.
Add your text subview outside of drawRect. drawRect is for rendering that one view, and may or may not ignore drawing any other views (such as your text view), depending on how the view stack is rendered.
Is there any reason to have it done in the drawRect method? You said that it works fine in the init method, so why not have it there?
As for why it doesn't work, I don't exactly know OpenGL views but, assuming they work just like regular UIViews, you probably shouldn't be adding other UIViews in the drawRect function. UIViews don't get shown & drawn immediately; they have to wait till the runloop tells them to draw. Likely what happens is that when your superview's drawRect finishes, it assumes all its subviews have finished drawing and doesn't realized that your newly added textfield didn't get a chance to. What you could try is calling setNeedsDisplay on your textfield.
set a UIImageView.image property to a UIImage is unable add the image to the view,however if i set the imageview frame property,it works.can anyone tell me how it's happen?
and what will happen when i apply the UIImage instance method[drawInRect:] redraw the image frame which is larger than the view frame?i have tried but nothing happen,and what is this function doing actual?
Generally, how it works is, you add an Image to a UIImageView and then add the UIImageView to a UIView to display it on the screen. You can do this programmatically, or using Interface Builder. Optionally, you can create a CGRect (based on a frame, if you like), use this as the bounds for the UIImageView (or you can frame the UIView). There are several ways to do what you want to do.
It's hard to tell without seeing your code. It could be a number of things. You could be inserting the view with the image behind the currentView? You may not be retaining the UIImageView. We can't read minds here necessarily, (sometimes we do). But you'll need to be more helpful if you want a solid answer.
Or just take a look at this:
UIImageView Docs