iPhone layer management - best practice - iphone

Louis - Thanks for your input. Here is what I did, and my current issues, which i don't understand.
The menus (2) are UIImageViews that respond to touch. Each is it's own class. The 'sprites' as you called them also respond to touch.
In the .m where I add the menus and sprites to the layer, I created two container layers, via this code: menuContainer = [CALayer layer].
I ordered them with the menuContainer above the spriteContainer. Now, the sprites do move below the menus - great! But in the process, the sprites stopped responding to touch (I can understand this as they are below the menuContainer layer), and the menus stopped responding to touch as well (don't get that). Continuing to confuse the situation, a layer added to the menuContainer that responds to a multitouch gesture by popping up a slider still reads the multitouch and pops up the slider, but I can't slide the slider. This has me thoroughly confounded.
Thanks.
My app is building a background layer, then building some menu layers that should always be at the top.
After this, I add many moving layers and remove many moving layers very quickly.
My problem is I want my menu layers (there are 4) to always be in front of the other layers. I have thought of building a layer hiearchy and using the insertsublayer: atindex: method, making my menus a notional index of 1000, and inserting the multitude of moving layers at a lower index, like 200. If I insert one layer at 200 and then the next at 200, does the first layer that was assigned to 200 get shifted (to 201) or does it get blown away?
I have tried inserting the layers with the insertsublayer: below:, but that does not give me the desired results.
Thanks for the help.

You can't really do that, the layer index is not a z-order, it is an array index. From the documentation:
This value must not be
greater than the count of elements in
the sublayer array.
I think you would be best served but actually making a true hierarchy of layers as opposed to trying to shove all of you active layers into one super layer. In other, but all of your menulayers into a container layer, then insert that in the root layer where you want it. Likewise, insert all your sprites into one container layer, and put that in the root layer where you want it.
Additional stuff based on your edits:
Layers are a essentially a graphical construct, they do not directly respond to events. You either need to handle that yourself by writing code to hitTest them in the view they are attached to, or you need to use UIViews instead of layers. You were probably getting away with it before because you were manipulating the layers in such a way that the view hierarchy and layer hierarchy were consistent, but it was not clear to me from your original question that you were using views and not a purely layer based setup.

Louis -
Thanks for your input. Here is what I did, and my current issues, which i don't understand.
The menus (2) are UIImageViews that respond to touch. Each is it's own class.
The 'sprites' as you called them also respond to touch.
In the .m where I add the menus and sprites to the layer, I created two container layers, via this code: menuContainer = [CALayer layer].
I ordered them with the menuContainer above the spriteContainer. Now, the sprites do move below the menus - great! But in the process, the sprites stopped responding to touch (I can understand this as they are below the menuContainer layer), and the menus stopped responding to touch as well (don't get that). Continuing to confuse the situation, a layer added to the menuContainer that responds to a multitouch gesture by popping up a slider still reads the multitouch and pops up the slider, but I can't slide the slider. This has me thoroughly confounded.
Thanks.

Related

endless vertical scrolling background

I want to make an endless vertical scrolling layer that gives the impression that the main character is moving upwards. I have been brainstorming on how to achieve this.
My issue is that I want objects to appear as if they are coming from above and below the screen at the same time. Secondly, I want to be able to move the main character to create and destroy box2d joints between it and some of the objects appearing on the screen. What is the best way to achieve this with consuming too much memory? I would appreciate any help on this.
Apple did a wonderful tutorial of this in a WWDC 2011 video session. It was "UITableView Changes, Tips & Tricks" and it's about 35m40sec into the video.
Since the use of the UITableView is really just a UIScrollView for the purposes of the background, you could just use a UIScrollView and you can either have it move on timer or events as needed.
Think of your player as moving within a stationary bounding box. The background can scroll using the aforementioned pooling method (as the background tile scrolls off the screen it is placed into a pool, and before a new tile is instantiated the pool is checked for available reusable tiles). Thirdly, your enemy objects will simply approach from either the bottom of the screen or the top.
Imagine your idea without the scrolling background (flying effect) and you should find that the problem is relatively straightforward.
I also needed and endless scrolling background layer. This can do exactly that, and it is super simple to set up and use. Just copy the four files in to the cocos2d folder in your project, then follow the quick tutorial seen on the github. Make sure the image you use is seamless (when you line them up vertically you can't tell where one ends.

OpenGL ES : Revealing underneath view

I am working on a sample in which I have placed two textures one above the other. What I want, whenever user moves his finger on the screen, underneath view should get revealed as he moves. Wiping out front view to reveal underneath view is what I am looking for.
I would like to know some of ideas/ thoughts to implement this feature using OpenGL ES. Any related pointer will be highly appreciated.
Thanks in advance.
This does not sound performance-intensive so simple code can trump complicated tuned operations.
You don't need to use OpenGL. You can simply have two images - front and back - with the front supporting an alpha channel. Each time you get a hit or move, you clear a circular patch whereever the impact is for some certain radius or such.
And then queue-up a redraw. The redraw draws the two bitmaps, back first then front.
If possible, try to queue a redraw for just the the area where you have updated the front since the last draw.

switching images with animation

I'd like to have a static background image (let's imagine a model in underwear), where several images are placed in layers in front of the background. Each image in front can be switched out, from the left or right, with some animation.
So our model might start with a panama hat on her head. A gesture replaces it with a porkpie hat, another gesture places a toque. A dress on her body switches to a pant suit, then mechanic overalls. Cowboy boots to sandals to galoshes, and etc.
It seems there are many ways to do this. I could use UIScrollView, with paging enabled. There is Core Animation, with CALayers on top of the background image. Even simple UIImageViews with swipe gestures enabled, tracking coordinates of the user's finger.
Does one of these techniques stand out as being better than the others in this case? Or does it seem to you readers that each could work as well as the others?
I'd say if you want a prebuild solution try OpenFlow (I'm not affiliated, just a user)
http://apparentlogic.com/openflow/
Otherwise, maybe just a UIScrollView with paging enabled would do the trick?

Advance way of using UIView convertRect method to detect CGRectIntersectsRect multiple times

I recently asked a question regarding collision detection within subviews, with a perfect answer. I've come to the last point in implementing the collision on my application but I've come across a new issue.
Using convertRect was fine getting the CGRect from the subView. I needed it to be a little more complex as it wasn't exactly rectangles that needed to be detected.
on XCode I created an abstract class called TileViewController. Amongst other properties it has a IBOutlet UIView *detectionView;
I now have multiple classes that inherit from TileViewController, and each class there are multiple views nested inside the detectionView which I have created using Interface Builder.
The idea is an object could be a certain shape or size, I've programatically placed these 'tiled' detection points bottom center of each object. A user can select an item and interactive with it, in this circumstance move it around.
Now the method itself works to an extent but I don't think it's working with the nested values properly as the detection is off.
A simplified version of this method works - Using CGRectIntersectsRect on the detectionView itself so I'm wondering if I'm looping through and checking the views correctly?
I wasn't sure whether it was comparing in the same view but I suspect it is, I did modify the code slightly at one point, rather then comparing the values in self.view I took the viewController.detectView's UIViews into the interactiveView.detectView but the outcome was the same.
It's rigged so the subviews change colour, but they change colour when they are not even touching, and when they do touch the wrong UIviews are changing colour
I worked out my issue when using convertRect.
I thought I'd read the documentation again (believe me I've been reading it) but I missed a key piece of information previously. To use convertRect:toView: to use the method the view needs to be target of the conversion operation as mentioned in the doc, but I was using the view itself as the target instead of the parent view
interactRect = [detectInteractView convertRect:[detectInteractView frame] toView:parentView];
This is wrong, I know there isn't many details in this post but ultimately you can't use the same UIView as the target view, or at least if you can I couldn't get it to work here!

Fast drawing in large-sized custom view

I'm developing Piano App for iPhone.
I'd like to develop smooth-scrollable keyboard (like Music Sampler).
I put a custom view(1440px x 120px) in UIScrollView.
I wanted to use OpenGL because Quartz is too slow.
But I couldn't make OpenGL view in 1440px.
Any idea to make a faster & large-sized custom view?
Thank you.
Any instance of UIView has a maximum size of 1024x1024. Doesn't matter if it is OpenGL or not. You can have a scrollable area larger than that, but you will have to build it from multiple tiled views.
Using OpenGL for this would be overkill and a bad idea. You'll waste a lot of time setting up things that are already provided for you in UIViews, such as touch handling.
There are two ways for laying out nonstandard keyboards on the iPhone that I've seen. The first is to create a static UIImageView that contains a representation of your entire keyboard, capture touch events within this view, and match the location of those touch events to where your prerendered keys are on the keyboard. If the user hit one of your virtual keys, you overlay some sort of image that shows the key popping out at you and you process the keypress. I believe this is the approach that many of the calculator applications take.
An alternative way is to set up each of your keys as separate UIViews, lay them out within a larger superview, and have each do processing of their touch events. This is what I do in the interface shown here. The lower menu consists of two submenus, and within the submenus each of the menu buttons are separate UIViews. Their content (the border, gloss, and text) is rendered via Quartz, but that rendering only happens once. Because these views are layer-backed, they cache their drawn content and animate and scroll very smoothly. Touch events trigger each menu item's action. Note that the top half of the menu is contained within a UIScrollView so that you can scroll for more options.
My personal recommendation is to use the latter approach, because dynamically drawing your piano keys at startup lets you experiment with different key sizes and shapes without having to redo your art every time.