I've built a screensaver for Leopard which utilises core-animation. It doesn't do anything overly complicated; uses a tree of CALayers and CATextLayers to produce a "table" of data in the following structure:
- root
› maincontainer
› subcontainer
› row [multiple]
› cell [multiple]
› text layer
At most there are 50 CALayers rendered on the screen at any one time.
Once I've built the "table", I'm adding animating the "subcontainer" into view using CABasicAnimation. Again, I'm not doing anything fancy - just a simple fade-in.
The problem is that while the animation does happen its painful to watch. It's jerky on my development machine which is a 3.06Ghz iMac with 4GB of RAM, and seems to chop the animation into 10 steps rather than showing a gradual change.
It gets worse on the ppc mac-mini the screensaver is targeted for; it refuses to even play the animation, generally "tweening" from the beginning of the animation (0% opacity) to half-way (50%) then completing.
I'm relatively new to ObjectiveC and my experience is based on using garbage-collected environments, but I can't believe I'm leaking enough memory at the point the screensaver starts to cause such problems.
Also, I'm quite sure its not a problem with the hardware. I've tested the built-in screensavers which use core-animation, and downloaded a few free CA-based for comparison, and they run without issue on both machines.
Information is pretty thin on Google with regards to using CA in screensavers, or using CA in general for that matter, and advice/tutorials on profiling/troubling screensavers seems to be non-existant. So any help the community can provide would be well welcomed!
--- UPDATE ---
Seems as though implicit animations help smooth things out a little. Still kinda jerky, but not as bad as trying to animate everything with explicit animations as in my solution.
There isn't much special about a screen saver. I assume you've started with the Core Animation Programming Guide? Running it through Instruments will give you a lot of information about where you're taking too much time.
The code you're using to do the fade-in would be useful. For what you're describing, you don't even need CABasicAnimation; you can just set the animatable properties of the layers, and they by default animate. Make sure you've read up on Implicit Animations. The rest of that page is probably of use as well.
Most of your job in CoreAnimation is getting out of the way. I generally knows what it's doing, and most problems come from second guessing it to trying to tell it too much.
Related
I've built a small Cocoa app that uses OpenGL to draw some light content. I've used CAOpenGLLayer. While the app itself is very small and works blazingly fast, the launch time of the app is not satisfactory at all. At random times the app would stall for about a second or two upon launch, before showing the content.
I've narrowed down the problem and found that the bottleneck is the CGLChoosePixelFormat() function that is called during OpenGL initialization. It literally takes ~1 second to execute.
For a clean experiment, I created a blank Cocoa app and added an NSOpenGLView to the window. Immediately, the app launch time has grown by 1-2 seconds, for the same reason.
Is there a way to fight this problem? There seems no way to avoid using CGLChoosePixelFormat(), it's essential for getting OpenGL to work on a Mac.
Also, it's said that Core Animation is built upon OpenGL under the hood, but my Core Animation apps do not exhibit this slow startup problem at all. Also, I tried a symbolic breakpoint on CGLChoosePixelFormat in a Core Animation app, but it doesn't trigger. So Core Animation is either not using OpenGL or there is a way to initialize it in a different way. Does anybody has a solution?
P.S. I know Metal is now the way to go for 3D graphics on Macs, but I need to do this particular project on OpenGL for backward compatibility reasons.
I've met the exactly same problem with you. So far I've found that the problem only occurs on MacBook Pro 16" 2019.
Since this problem is hard to reproduce, I can do nothing more than guess. For now I have changed the NSOpenGLPixelFormat initWithAttributes: method to [NSOpenGLView defaultPixelFormat], and hope it will work.
In iOS, I'd like to have a series of items in "space" similar to the way Time Machine works. The "space" would be navigated by a scroll bar like feature on the side of the page. So if the person scrolls up, it would essentially zoom in in the space and objects that were further away will be closer to the reference point. If one zooms out, then those objects will fade into the back and whatever is behind the frame of refrence will come into view. Kind of like this.
I'm open to a variety of solutions. I imagine there's a relatively easy solution within openGL, I just don't know where to begin.
Check out Nick Lockwood's iCarousel on github. It's a very good component. The example code he provides uses a custom carousel style very much like what you describe. You should get there with just a few tweaks.
As you said, in OpenGL(ES) is relatively easy to accomplish what you ask, however it may not be equally easy to explain it to someone that is not confident with OpenGL :)
First of all, I may suggest you to take a look at The Red Book, the reference guide to OpenGL, or at the OpenGL Wiki.
To begin, you may do some practice using GLUT; it will help you taking confidence with OpenGL, providing some high-level API that will let you skip the boring side of setting up an OpenGL context, letting you go directly to the drawing part.
OpenGL ES is a subset of OpenGL, so essentially has the same structure. Once you understood how to use OpenGL shouldn't be so difficult to use OpenGL ES. Of course Apple documentation is a very important resource.
Now that you know a lot of stuff about OpenGL you should be able to easily understand how your program should be structured.
You may, for example, keep your view point fixed and translate the world (or viceversa). There is not (of course) a universal solution, especially because the only thing that matters is the final result.
Another solution (maybe equally good, it depends on your needs), may be to simply scale up and down images (representing the objects of your world) to simulate the movement through the object itself.
For example you may use an array to store all of your images and use a slider to set (increase/decrease) the dimension of your image. Once the image becomes too large for the display you may gradually decrease alpha, so that the image behind will slowly appear. Take a look at UIImageView reference, it contains all the API's you need for it.
This may lead you to the loss of 3-dimensionality, but it's probably a simpler/faster solution than learn OpenGL.
Being a somewhat proficient iOS developer, I have just started working on a desktop OSX project in Cocoa and I'm running into issues that I just can't grasp. So this question is for the OSX developers out there.
I don't like the Interface Builder much, so I tend to write my views in code. The most prominent method I write my view layout code in is a view controller's loadView method, and at least on iOS I use autoresizingMasks for everything. Try out the view small, large, rotated landscape and portrait and if all is dandy, I continue with the next item on my list. Now on the desktop, the autoresizingMask works (or just looks) a little bit different. First of all the properties have different names, but their behavior also seems weird or unexpected.
When I ran into the issue below, I thought it must be my code was wrong, so after trying out long enough I re-created it with Interface Builder just for confirmation's sake, and guess what: I got the exact same result. Take a view with four vertically stacked subviews. Set the middle two to have flexible heights, the outer ones to be fixed. When you run it, size it down and back up again, I get two completely different layouts before and after the resize. See image:
Now I can follow why this happens from a mathematical standpoint between run loops, but from the point of an 'autosizing' or 'autoresizing' feature, this makes absolutely no sense.
Before I try to write the mother-of-all-resizing-topics here, might I ask you these questions? Feel free to elaborate some more on the resizing topic if you feel it adds to the post.
Am I a fool for not wanting to use the Interface Builder on desktop projects?
Should I depend on the autoresizingMask less than I would on iOS projects?
What are decent alternatives to making sure your layout lives up to standards without Interface Builder?
Cheers!
Yes, in my opinion. :)
You should depend on it when it does what you need. When it's insufficient, override resizeSubviewsWithOldSize: and/or resizeWithOldSuperviewSize: (or see below).
???
If you can target 10.7, look at the new constraint-based layout system. Check out the Cocoa Autolayout video from WWDC 2011.
You could also set minSize on your NSWindow to something large enough to prevent the singularity.
I'm not sure I'd say "fool," but refusing to use Interface Builder on the Mac is a very…avante-garde choice.
You should definitely use autosizing on your views.
Be maniacally attentive and spend lots of time making sure everything is right. (This is why I don't recommend going without Interface Builder. In general, what you get is a lot of wasted time that you could have spent doing something else.)
In this case, I think the best approach would be to set a sensible minimum height for the window. Don't let it get too small to display what it needs to display.
I have been searching around and it looks like this question has been asked quite a few times in various places with no answers or responses. That means that I can't be the only one experiencing this.
There is always a delay in the scrolling when you try to scroll a list or panel for the first time. After the first time you scroll a list or panel, there is no longer any delay. Is there a way I can simulate this "first touch" in an effort to remove the delay when attempting to scroll a list or panel for the first time?
I've been looking through the ScrollView and Scroller code and have not been able to find a point where anything heavy or expensive is happening on a first touch.
Any help or direction on how to remedy this would be greatly appreciated.
Thanks!
You can open the Chrome/Safari developer tools and start profiling("Profiles" tab) to see if there is any JavaScript code that is performing badly and causing the hang.
If it's not code that hangs, it might be a web browser issue (e.g. image cache allocation), for example due to the first time that things dynamically change in your web app.
It's also important to try and compare platforms and see if they have the same issue.
It's also often helpful if you specify the Sencha version (I assume 1.x?) and the platform(s) you've had the issue with. iOS/Android/PC can often react quite differently.
I'm in the midst of porting a win32 app to cocoa. Wherever possible, I'm using IB, since... well its way easier in every way possible, obviously. One thing is the designer and the win32 dev set up all the button assets on a massive "sprite sheet" such you move around the viewport to determine button state. Similar to how yahoo does CSS sprites on their home page (http://d.yimg.com/a/i/ww/met/pa_icons/20100309/spr_apps_us.png)
Can IB be setup to handle this type sprite strip with the default buttons, or are we SOL on this one? I can certainly fire something up programmatically that would do this, but would like to incorporate as much of the default button behavior and selector hookup in IB.
Thoughts?
Josh
This isn't supported in IB because it is really not a Cocoa way of setting button images. I understand why you would use sprites in CSS but in a native program (on any platform) it seems really unnecessary and inefficient.
I honestly think it would be much less work for you to forget about using the sprites. Out of curiosity, are these buttons going to be for standard user interactions, or something more along the line of buttons for a game? If it is for standard user interactions (open file, change font, etc.) then I strongly recommend using the stock buttons as much as possible, although I understand that this might be out of your control. The reason is that the worst ported apps are usually the ones that try to keep visual fidelity with their Windows counterpart.