UIScrollView stops (or slows down) scrolling between stops defined by Paging - ios

I have an iOS App that uses Unity3D. When I pause Unity to show only Quartz-related content, the performance is usually fine.
But on a current project, scrollviews and table views sometimes perform very bad. They stop scrolling too early, and the scrollview stops even between multiples of the size predefined by the paging.
I tried to take a look with Instruments, and found FPS is usually ~50-60, but sometimes less. However this does not answer my question.
Btw, the table and the scroller have only a few data, and there is no reloading issue.

Okay, now I found some very helpful information at the Unity Forum. Using
#define USE_DISPLAY_LINK_IF_AVAILABLE 0
prevents the described issue. The Unity-iOS project now uses THREAD_BASED_LOOP instead of the CADisplayLink class. Maybe I will further play around with CADisplayLink and lower target frame rates.
Some interesting information about the used Rendering Loop Type can be found in the Unity Manual.

Related

Slowly swiping down to refresh on refreshControl of UITableViewController causes view to jump down

I used to have a UITableView in a UIViewController. I would put a UIRefreshControl on the UITableView and on the very last bit of swiping down to refresh, the UITableView would quickly jump down.
All answers voiced the same: Undocumented/unexpected behavior (being able to use UIRefreshControl with a UITableView) yields such results. To mitigate this, I used a ContainerView to embed a UITableViewController in a UIViewController.
I have nearly solved this issue, but... if I swipe down slow enough, the problem persists.
Is there any way to mitigate this, or am I forced to live with it?
Video: http://streamable.com/8suq
Notice the first few times I swipe down look absolutely fine because I do it fast enough, but towards the end of the video I really slow it down and you notice the jump in question.
I notice that you have a mouse cursor in that video. You cannot judge graphic performance for animations in the simulator, it will not perform the same as on an actual device.
On a device you will get much better performance and a much better frames per second rate. I've seen this to be very noticable when using SpriteKit whilst learning to develop games lately.
I've only used the UIRefreshControl a couple of times previously in a UITableViewController and not noticed any major issues before. Since then I've been using other libraries such as https://github.com/samvermette/SVPullToRefresh.
Try your app on a physical device and in the meantime I will try to replicate your issue and add my findings in here

Animated constraint change layoutIfNeeded slow

I'm trying to animate a my ADBannerView on and off screen using autolayout. Pre-autolayout (setting frame and animating) everything worked fine. Now I have the following code and it runs on viewDidLoad to make sure the ad banner if off the screen.
[UIView animateWithDuration:kADAnimationDuration
animations:^{
_addBannerDistanceFromBottomConstraint.constant = 32;
[self.view layoutIfNeeded];
}];
This code work, but it is slow. layoutIfNeeded is taking a long time (relatively) and causes poor performance. Removing the line makes everything nice and fast, but the animation doesn't work.
The question is... why is this so slow/how do I speed it up?
Edit: My UI is fairly significant and I thought laying out everything might be the cause, so I tried creating a simple UIView and putting my banner in there as a subview, then I only needed to call layoutIfNeeded on that subview with 1 item in it. No change in performance though.
I created an app with the ADBannerView and nothing else. Same problem existing. I submitted to Apple as a bug and got "duplicate" so I guess it's a known issue.
As a workaround I'm starting with the ad banner off the screen and moving on the screen only when I get a valid ad. While it's slightly more annoying to work with in the storyboard, the user won't notice the difference and it prevents the slow down.
Edit: I've been working more with auto layout and I've come to a unfortunate conclusion which I seem to share with Matt Neuburg. In bit he wrote titled "auto layout slow on iOS" he said:
It's a pity, but auto layout is slow on iOS.
It pretty much has summed up several issues I've been having converting one of my apps to auto layout. The performance is simply not there. The example Matt gives in his post has auto-layout taking 5 times longer to accomplish the same task.
For now, I guess I'll be avoiding auto layout for anything complicated enough for auto layout to be useful.
Edit: iOS 8 is in beta and constraints have gotten significantly faster. There is still when using a lot (50+) especially on older devices but from testing so far the formerly 2 second delay I was getting has been reduced to about 0.4 seconds. With this change constraints may have been sped up enough to be viable for some constraint heavy view work.
One problem might be doing this in viewDidLoad, where view parameters haven't been set up yet, though, I don't know why that would make it slow. You might try it in viewDidAppear instead. Also, according to what I saw in the WWDC 2012 auto layout sessions, you should add the constraint (or modify the constant as you're doing) outside the animation block, not inside. Try moving it above the animation block.

Sticky UITableView scrolling in Unity

I am building a UITableView-based Unity plugin which will be embedded by game developers into their Unity app. I am using the standard approach with dequeueing reusable cells, and the UITableViewCells contain simple UILabels and a UIImageView. The image inside the UIImageView is loaded via an asynchronous request.
There are no usability issues at all when launching the plugin as a standalone Objective-C app (in particular, scrolling works well with no lag) but when inside Unity, there is a "sticky" scrolling issue which arises randomly, i.e. the view scrolls but without inertia. I have not been able to pinpoint the exact actions which cause this behavior, but it happens usually when I scroll very quickly in one direction, or in short movements back and forth. The bug disappears when I scroll the view past the top or bottom (trigger the "bounce" effect, I am guessing this causes some hard refresh).
There is a very similar issue described here. The fix they suggest is to put
#define USE_DISPLAY_LINK_IF_AVAILABLE 0
inside the Unity-generated AppController.mm file. Unfortunately, this fix is unfeasible for the game developer who will be integrating our plugin, since it turns off the fastest and most reliable timing solution, and would require a fallback to other timing systems which would cause the game itself to lag or miss a portion of touch and accelerometer events.
I will most likely override drawRect for the UITableViewCells to reduce rendering time and memory usage, and if that fails, write a version of the plugin in OpenGL. However, I was wondering if anyone had a similar issue and knows a quicker fix, either in Objective-C or inside Unity, that is non-destructive (like the timing fix described above). Thanks very much.
I had the same trouble that you have described. I've fixed it by commenting the line
//#define USE_DISPLAY_LINK_IF_AVAILABLE 0

Jittery WebGL Scroller

I've built a scroller prototype using WebGL. The problem is, when it's combined with other non-WebGL elements on the same page, the scroller becomes jittery and the quality is quite poor. You can see a demo here (scroller is at the bottom, ignore the Chinese characters) - http://viewer-test.appspot.com/Viewer.html?type=presentation&id=6a169bb8-e440-4338-9e3a-8b5e429f32ee&showui=false Even if I take out the video, the scroller still slows when the CPU spikes every time that RSS feed top right shows a new feed snippet.
I had considered using Web Workers to run the scroller on a different thread, but came across another post in this forum that said that Web Workers can't be used with WebGL. What are my other options to ensure smooth scrolling?
Thx.
Are you using RequestAnimationFrame for your animation callbacks? If not, you should. It's managed by the browser to time the draw of your element with the others on the page and with the system screen sync, so you get the smoothest presentation possible. If you do your animation using setTimeout or setInterval, you'll almost always end up out of sync with the pages rendering, which leads to dropped frames and stutters.

iPad performance issues

I have this problem with performance of my iPad app..
For developing, I use MonoDevelop, which takes care of Garbage collecting. Still my questions are rather generic, I'd say.
OK, I use TabBarController with 5 NavigationControllers. Inside nav controllers there are some controllers, whose views are TableViews or ScrollViews. Next child is always just regular view.
I have a few questions:
1) TableViews never scroll smoothly. I have some alpha transparency, but since I did my graphics in Photoshop and not programmatically, this transparency should not cause much problems. It doesn't matter whether I have few or many results in table.
On the other hand, I have ScrollView which serves same purpose, i.e. to be a table with different layout and buttons have Photoshop generated transparency as well. It works perfectly.
For tables I applied DequeueReusableCell() which works fine (I see that memory usage is not increasing after scrolling). So why would tables scroll so jerky?
2) My app supports rotation. When I scroll table or scrollView and simultaneously tilt the device a bit, I get maybe 1 or 2 FPS. What is the best way to implement rotation? As I understand, ShouldAutorotateToInterfaceOrientation has to be overridden in all controllers in NavigationController chain. Also, I need to add observer in View I want some changes to happen. Do I have to use BeginGeneratingDeviceOrientationNotifications() in all views or is it enough to do it in Main.cs? Maybe this slows it down?
3) After some time app starts getting memory warnings and then crashes eventually. I tried to read logs and run app with Instruments, but can't find the cause of crash.
4) What exactly happens to a View popped from NavigationController stack? I can't reuse it. But could it be that Monotouch (or me) doesn't dispose it correctly?
I have almost same app for iPhone without support for rotation which never crashes. I think I'm doing something wrong with this rotation, but I'm not sure what.
Any help will be appreciated the most. So, thank you in advance.
Regards
1 - transparencies are always a problem. Even if you're not rendering the images in code, the phone still needs to do the compositing of the image, and that may take a lot of time. UITableViews have to calculate the final composite image every time a new cell is displayed, or the table is scrolled, while UIScrollViews can calculate only once, since the image won't change. So be very careful about it, turn the transparency off, and check if performance improves.
2 - You shouldn't need to notify every uiview in your application. Receive the notification in the controllers that you want to update only, like for example if you want to rearrange items in the UIViewControllers view.
3 - you have one (or many) memory leaks. My guess is that MonoTouch probably can't garbage collect UIViews or UIViewControllers, because they're still being linked from somewhere in UIKit, like a UINavigationController
4 - UIViews are not disposed by UIKit until the app gets a memory warning notification.
Like Eduardo said, alpha transparency in Views comes at a price. There are some tools that you can use to identify the bottlenecks discussed in these WWDC 2011 talks from:
https://developer.apple.com/videos/wwdc/2011/
iOS Performance and Power Optimization with Instruments
Understanding UIKit Rendering
In the "Debug" menu of the iOS simulator you can find various debugging tools that will color different regions of the screen indicating where some problematic rendering is taking place. The WWDC 2011 talks show what you can do to fix those problems.
For your memory problems, it is very likely that you have something pointing out to your objects around, so you need to make sure those objects are gone. While we currently are not shipping our new profiler for MonoTouch that can show the source of the problem, I wrote a "poor man's" debug utility that will help you narrow down which objects are alive. It is available here:
http://tirania.org/tmp/HttpDebug.cs
Call HttpDebug.Start () from your application and as you run, connect with a web browser to http://localhost:5000 to get a list of live Objective-C objects surfaced to C#. The tool is not perfect and shows a lot of irrelevant data, but it would at least give you an idea of what is going on.

Resources