Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for views on top / bottom and rotation about the x-axis #6

Open
jamiebullock opened this issue Jul 23, 2013 · 3 comments
Open

Comments

@jamiebullock
Copy link

It would be great if this control optionally supported adding of views to the top bottom of the cube. So that if I have a view on the top of the cube and I drag downwards, the cube rotates about its x-axis, with the top edge of the cube being pulled down bringing the top UIView onto the screen. Likewise with a view on the bottom of the cube, dragging upwards would bring the bottom view onto the screen.

I think this would only work if the GKLCubeViewController is a cube though. Unless for prisms the top / bottom views are never allowed to become the main view, i.e. x-axis rotation is constrained to a certain angle.

@pyro2927
Copy link
Owner

I'll consider it for now. The problem with this is that you then can't use UIScrollViews/UITableViews as they take over the swipe up/down gesture. You're also right in that the it only works if there are 4 sides, making it a cube. The non-cube-support branch is looking good, and I'd rather lean in favor of that over having a top/bottom to the cube.

@robertmryan
Copy link
Collaborator

Agreed. But, @jamiebullock, hopefully if you look at the code you could see how you could do this yourself. The basic trick for doing these sorts of cube transformations is to do a negative z transform to the point of rotation (in the case of a cube, it's half the width of a side), rotate 90 degrees (M_PI_2 radians) about the appropriate axis, and then do a matching positive z transform (so the edges match up again ... which, by the way, is why, when you tried adjusting one of the transforms in your earlier question, the edges no longer matched up).

When you tackle this, there are going to be a few challenges, though:

  1. Right now, the class is using the array of child controllers as the model. Clearly, an array isn't going to be enough to capture the relationships between the sides of a cube, so you'll have to have some other backing model. You may also want to abandon this class' notion of pre-loading the child view controllers in advance, and move to a delegate model, akin to what you see with UIPageViewController.

  2. As pyro2927 pointed out, the current solution depends upon the views not having gesture recognizers that conflict with the cube rotation gestures. That's relatively safe when rotation is only about the y-axis, but
    Imposes further restrictions if you want to rotate about the x-axis, too. And the usual trick here, creating a custom gesture recognizer that only recognizes gestures from the edge and then defining the scrollview to require the edge gesture to fail first, will introduce a challenge when trying to set up edge gesture on the x-axis because iOS already has a top edge gesture to pull down the notifications window. In short, if you want to rotate about both the y-axis and x-axis, it may preclude your use of any child views with any pan gesture recognizers of their own.

  3. Even if you decide you're ok with that restriction, you will probably not want to use a standard pan gesture at all. You'll probably want to write your own custom y-axis pan gesture and custom x-axis pan gesture. Not difficult, but subclassed pan gesture recognizers will probably be useful for your exercise.

  4. Finally, you'll have to think about how you want to handle some idiosyncrasies of rotating about both the y and x axes. Specifically, if you rotate about the x-axis once, and then rotate about the y-axis, the view that was originally to the side will have been rotated 90 degrees, so you'll have to figure out how you want to handle that scenario. The width and the height won't match up and it will be rotated. I can imagine that you might "auto rotate" the side views as you rotate up and down the y-axis, but this sort of breaks the "real-world" cube feel (which may be fine, but should be a conscious of this).

    But to my first point, if you go to the delegate approach for loading child view controllers, this problem is mitigated.

Bottom line, while none of this is rocket-science, there's a lot of work in this seemingly simple request. I'd suggest you take a crack at this yourself and share your progress with us. But hopefully the techniques employed in this class (the custom container view controller with the appropriate containment calls, the use of multiple CATransform3D transformations, etc.) will be useful as you tackle this.

@jamiebullock
Copy link
Author

Thanks guys, this is really helpful. I don't need an arbitrarily rotatable cube for my purposes, but rather that the cube simply exposes its top or bottom view by about 30 degrees when pulled up or down from a bounded area in the main view and to flick back when the finger is removed from the screen. I just wanted to phrase the request in such a way that it might be of more general interest.

I definitely have enough info to implement this myself, so I'll work on it and report back if I have something that might be reused.

Thanks again for @pyro2927 for making this class available in the first place, and and @robertmryan for all the extra advice and input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants