I was playing around with the same sort of problem a while ago and hacked together a quick demo of one solution. Off hand I'm not sure if a map view, which might be built of many tiles, would be easier or harder to manage.
https://github.com/jonah-carbonfive/WrappingScrollView
Here's what I'm doing in case it isn't clear from the code.
- Create a single view containing whatever content you want to display. We'll call this the "tile view".
- Display your tile view centered in a UIScrollView's content view. Make the content view significantly larger than the tile view (see below for how much larger).
- Create an image of the contents of your tile view.
- Create UIImageView "tiles" containing this image and position them around the tile view to fill your scroll view's content view. That might be a lot of UIImageViews but they share a single image so the memory footprint isn't too bad.
- Now you have a large scroll view which appears to wrap it's contents at least once but you'll still hit the edge if you scroll far enough.
- In the scroll view's
-scrollViewDidScroll:
delegate method check if your tile view has scrolled completely out of sight, if so reposition the scroll view's content offset to reposition the content view so the tile view is back in the middle of the visible region. Done correctly the user never notices that you jumped from looking at an image of the tile view back to the tile view itself.
- But wait! Only the central tile view will actually respond to touches. All the other copies of it are just images after all. We can work around this by overriding
-hitTest:withEvent:
to reposition the tile view to take the place of whatever image view the user attempts to touch before calling super
. Now all touches reach the tile view.
- Make sure to update the image of the tile view any time the tile view is redrawn.
That's kind of crazy but it let me throw arbitrary interactive UIViews and UIControls into a container and let them wrap off one side and back onto the other.
Honestly this is probably not a great solution for you. If I knew that I wanted to draw a map which could wrap in one or more dimensions I would break the map into many tiles. Detect touches on some container view much like UIScrollView does, and reposition the tiles as the user moves their touches. Removing tiles as they scroll out of sight and reusing them to show newly visible regions of the map.
In a simple case you might be able to implement this using just two copies of a map image. In a complex case you're recreating much of UIScrollView; scaling the tiles you display and possibly loading different tile sets at different resolutions to reduce memory use and increase resolution while zooming.