I have UIViewController with many UIButtons (>30). But my animation between previous and next views is slow and with spurts. If I commented all of buttons - animation is going to work correctly. How can I fix this problem? My project use ARC mode (in this I think couldn't be memory leaks)
Related
I have an iOS app where I use a lot of UIView animations. They'll all work perfectly for a very long time, then suddenly all animations finish instantly instead of using the specified duration. No errors and the app still functions, but the animations don't work properly.
The app will do a lot of downloading small graphic files in the background then call a selector on the main thread to present the graphics.
Does anyone know what may cause this kind of behavior?
I know it's not okay to handle UIKit in backgrounnd threads but thought it was limited to all drawing, like adding subviews etc. It seems creating and changing views (without adding them as subviews) is not okay either. My problem in particular was creating UIImageViews in a background thread. I changed the code to load into UIImages and create the UIImageViews in the presentation code, which is run in the main thread and now it's completely stable.
I have a following situation (testing on iPad, iOS 5.1):
There is a UIPopoverController with UINavigationController inside and custom popover background view (subclass of UIPopoverBackgroundView).
There is a generic UIViewController (let's call it VC1) as the root VC in the Navigation Controller.
I push another UIViewController (VC2) with UITableView on the Navigation Controller stack.
Effect:
Table scrolling is choppy (looks like 10-15 fps). For testing purposes I use a simplest possible UITableView, without images etc. so it's NOT caused by bad UITableView implementation.
Scrolling is not choppy if the VC2 is the root view controller of
Navigation Controller, even with the custom Popover background.
It's also not choppy if pushed as the second VC but I don't use custom bg view class for UIPopoverController.
I log each of the overriden methods inside my UIPopoverBackgroundView subclass, and they aren't called constantly or anything, which could theoretically cause performance hit. I'm going to debug the problem further but maybe someone has already solved it before?
Or maybe someone has good suggestions on how to find the culprit? I tried looking into time profiler for offending function calls, but I didn't find much there...
I have a strange problem when using a UIScrollView controller combined with iPhone 4 and iOS 5.1.
I have a UIScrollView which has a content size of 640x480 (double screen effectively) and in addition to the swipe to switch between the two "screens" I also permit the user to tap the screen in response to which I call something like...
[scrollView scrollRectToVisible:(CGRectMake 320,0,320,480) animated:YES];
the first 320 would be 0 if the tap occurred whilst the right hand side of the scroll view was displayed (note the scroll view has paging enabled so it can only come to rest either fully left or fully right).
I also have a situation where I sometimes display an additional view controller modally using presentModalViewController over this view controller containing the scroll view.
Everything works perfectly until the modal view controller is presented and subsequently dismissed after which the scrollRectToVisible method will no longer work if animated is set to YES (if I change animated to NO then it works as expected). Note, the tap is still being registered and the scrollRectToVisible being called, it just doesn't do anything when animated is set to YES).
Here's the kicker, this bug only occurs on an iPhone 4 runnings iOS 5.x.
It works perfectly (even after the modal view controller has been displayed) on my:
iPhone 3G running 4.x,
iPhone 3GS running 3.x,
iPod touch (2nd Gen) running 4.x
and most surprisingly the simulator running 5.x.
I wondered if this was a bug in the animation system so disabled the animation on the modal view controller presentation and dismiss and this had no effect, problem still occurred on the iPhone 4 with iOS 5.1.
Anyone got any ideas as to what might be causing this and how I might work around it?
Finally tracked this down. what a pig...
I'm embedding a view from a view controller as a subview of another view controllers view. So my scroll view contains a view which also has an associated view controller.
Prior to iOS 5.x the methods viewWillAppear, viewWillDisappear, viewDidAppear and viewWillDisappear are never called on the sub views view controllers, only the main view controller. Already knowing this I set up my main view controller to manually call the sub views view controllers methods when these events happen.
However it appears that in iOS 5.x this issue has been "fixed" so where I was manually passing the call to viewWillAppear to my sub view controller I no longer need do this under 5.x as the method automatically gets called under 5.x - as a result it's now being called twice under 5.x but still only once when running on a 4.x or earlier device.
As a result, under 5.x my NSTimer used to call my updateUI method is being created twice, but because in viewDidDisappear I only destroy the timer if it is non nil it only gets destroyed once - therefore I'm leaking NSTimers under 5.x through double allocation where I'm not under 4.x.
As a result of multiple NSTimers hanging around all repeatedly calling my updateUI method is that the constant updating of the UI is killing the animation system and so the animation for the scrollView fails when running on an actual device. I guess it continued working OK on the simulator running 5.x as the CPU in the Mac is more than capable of handling the extra workload and still performing the animations correctly.
A simple check in my viewWillAppear method to ensure the NSTimer hasn't already been created has fixed the problem and has kept compatibility with 4.x and earlier.
I frustratingly run up against these kinds of issues every time Apple update their iOS by major versions... The morale of this story is don't assume that long standing classes still exhibit the same behaviour under different revisions of the OS.
I had the same problem. I realized that after modalViewController is dismissed my UIScrollerView shifts downs by 20px, which is the same height as status bar. So, it means when my UIViewController is loaded and UIScrollView is created, UIScrollView thinks there is no status bar, when actually it is there.
So I tried to put in viewDidLoad:
[[UIApplication sharedApplication] setStatusBarHidden:NO];
Now my UIScrollView always stays under status bar, with Y position 20px. It never shifts down.
I finally managed to get this working on an iPhone4 running 5.1. Ensuring the bounces horizontally property for the scroll view is set fixed the problem, though why having this unchecked should cause the problem in the first place is beyond me - I'm pretty certain this is a bug in iOS.
So been working on another app recently for iOS which incorporates a UIImagePickerViewController. App is ready to go and all works fine under normal circumstances, but if the user is being eratic and pushing buttons whilst rotating the iPad, then things go slightly awry and views load in the wrong place.
So basically, I want to disable all my buttons before the iPad is rotated and enable them again after the view is done rotating.
I thought this would be easy using the
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
and
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
methods.
But because the UIImagePickerController is being displayed, this for some reason stops these methods from being called. So I can't use these methods.
So basically, what I'm asking is if anybody can think of any other ways that I could achieve this??
Thanks,
Matt
You could subclass UIImagePickerController and then implement those methods on your UIImagePickerController subclass.
In my application, I have a UIViewController with a subclassed UIView (and several other elements) inside of it. Inside of the UIView, called DrawView, in my drawRect: method, I draw a table grid type thing, and plot an array of CGPoints on the grid. When the user taps on the screen, it calls touchesBegan:withEvent: and checks to find the closest point on the grid to the touch, adds a point to the array that the drawRect: method draws points from, and calls [self setNeedsDisplay]. As the user moves their finger around the screen, it checks to see if the point changed from the last location, and updates the point and calls [self setNeedsDisplay] as necessary.
This works great in the Simulator. However, when run on a real iPhone, it runs very slowly, when you move your finger around, it lags in drawing the dot. I have read that running calculations for where to place the points in a different thread can improve performance. Does anyone have experience with this that knows this for a fact? Any other suggestions to reduce lag?
Any other suggestions to reduce lag?
Yes. Don't use -drawRect:. It's a long and complicated reason why, but basically when UIKit sees that you've implemented -drawRect: in your UIView subclass, rendering goes through the really slow software-based rendering path. When you draw with CALayer objects and composite views, you can get hardware accelerated graphics, which can make your app FAR more performant.