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.
Related
I am fairly new to developing for iOS. I have a fully functioning program written in Swift and the UI was created in the scene builder on Xcode. I created an app for my work to simplify closing out the registers and other financial aspects. The app is complete and works perfectly, but was designed on the iPhoneX. The problem is that only a few of the employees have an iPhoneX, but they all have some kind of iPhone. I have tried setting up constraints but it never works. Ive tried scaling restraints and position restraints but I can't get the layout to look right on any other phone, and when I add the constraints it affects the view on the iPhoneX as well and doesn't look good on any iPhone. I need help getting this to work on all iPhones. I would like it to look and act the exact same regardless of the size of the phone, basically just scaled down. There are a lot of things on the screen and I can't figure out how to do this. Please help!!!
I have been working on this for a long time and I really need help. Please let me know if I need to clarify anything. I have posted links to some pictures of my UI so you have an idea of whats going on.
Constraints I tried adding, although I have played around with some other options.
Here's what it looks like on the iPhoneX, this is how I want it to look.
What it looks like on iPhoneSE (with constraints).
One thing I noticed in your Xcode project that none of your features are in UIView. Without it, it will be quite challenging and somewhat always different results. In theory, if you use AutoLayout features correctly it should work without UIView, but they make life so much easier. This is something I learned the hard way at the beginning of my iOS development. First set up your UIViews without any content inside it, give them some background colour to differentiate, once they are working on all devices. You can pin your features to superviews with no difficulty.
Since you have a repetitive features, you could also consider using Stack Views. You don't have complicated features, so as long as AutoLayout is set up correctly you should have no problems seeing it ok on all devices
We have a utility app that has like 10 major animations for manipulating the UI. A new developer suggested that we convert from managing position in code to using AutoLayout. We have tried this once before and it just really didn't work (and all constraints in code) and the constraints would break. Are we being Luddites by not adopting AutoLayout or are major projects not using it?
Has anything significant changed where this would be easier from 18 months ago? My feeling is that if we don't absolutely need it, we're better off staying just manipulating frames in code.
Using autolayout is necessary because the screen sizes vary so much. Trying to modify layout constraints manually to mimic what you currently have can be a HUGE head ache.
A solution is to move the animation code into storyboards (well as much as possible anyway). The code you have to maintain will most likely shrink dramatically from pre-autolayout to using autolayout (depending on the animation type). Here's a tutorial
I am having real difficult time using auto layout as when I sometimes change the views, it becomes a real mess with the already assigned constraints. So should I really give more time to myself learning auto layout or should I just go with multiple storyboards as it takes a bit of time but ultimately makes it easier for us to change the design easily in future.
From my learning,
I felt the same because its hard to learn and understand AutoLayout for first time. Here is the lot of advantages using
AutoLayout Advantages
Future iOS Versions going to support auto layout
It will save you lot of your time when ever new version of OS get released
Using Multiple StoryBoard
You need to maintain for each screen which is clearly hassle if you want to change anything in your View.
It will eat lot of your time to fixing
and much more
Spend little time in AutoLayout. Its not that hard to learn.
Auto Layout
Size Class Explanation
I am sure above link will help for all beginners.
The practice we are using is always splitting the Storyboards into smaller chunks, because they get ridiculously big and hard to work on. But we are not splitting them for different devices, but feature-wise. For example the Onboarding process has a separate Storyboard.
But we are always using auto-layout and iOS 8 size classes to support different devices. In some cases we even code constraints in code.
So learn Auto-layout sooner rather than later, it will save you time on multiple occasions.
In new Xcode you can find Size Classes in Storyboard which helps to manage various screen sizes. On beginning it seems to be hard but after little time it will save you lots of work.
I suggest to start here: https://developer.apple.com/library/ios/recipes/xcode_help-IB_adaptive_sizes/_index.html
It is important to create proper constraint. Set on view size class: Any x Any and then you can create constraints automatically, clicking Editor -> Resolve Autolayout Issues -> Reset To suggested Constraints or use shortcut: Command + Option + Shift + "=" while object in storyboard is selected. Honestly, it doesn't work properly in each case, sometimes you just have to set it manually.
Summarizing it's worth lo learn AutoLayout and make all screen sizes in one Storyboard.
I am not really sure how to phrase this question but to keep it simple;
I originally started my app for iPhone but now made it universal. Being that did that, I started making iPad.xib files as well... Everything is complete now and everything is working how it should except ONE thing...
On the Controllers, I have an instructions button, (button that when touched, a uiview gets added to the center of the screen and says the instructions).
That all works great but for some reason when I touch it on one of the new iPad Controller (from the iPad xib) all the buttons that were moved around the view prior to touching the button, start to revert back to the initial position...
I do have a function that makes them do that, but to my knowledge, it is not being activated when this instructions button gets touched. If it were, I'm sure this "error" would also happen in the iPhone simulator...
Anyone have any idea? I keep looking at different solutions but can't really figure this out.
Thanks!!
This is most likely due to auto layout. If you change the frame of a view by setting frames, when the view updates (for any reason), the views will revert to the frames that are determined by their constraints. To fix the problem, you should move your buttons around using constraints, or turn off auto layout. While turning off auto layout is the easy way to fix this, you really should learn how to use that system.
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