Question

In a what would be a (yet another) word game for iOS I have a scroll view holding an image view with game board.

And underneath I have draggable custom views representing letter tiles.

For the scroll view I've added a double tap gesture recognizer for toggling its zoomScale (between 50% and 100% image width):

app screenshot

This works well, but I had to disable Autolayout (because otherwise scroll view's contentOffset would jump to {0,0} when I dragged the tiles).

So I had to add the following code to ViewController.m to adjust scroll view's frame after device rotation:

- (void) adjustSubViews
{
    _scrollView.frame = CGRectMake(0,
                                   0,
                                   self.view.bounds.size.width,
                                   self.view.bounds.size.height - kHeight - 2 * kPadding);
}

this seems to work too - but my problem is that after first device rotation to landscape and back "something breaks" and the tiles are suddenly draggable by touching underneath them:

app screenshot

Why does it happen please?

Below is an Xcode screenshot (here fullscreen) showing the scroll view properties:

Xcode screenshot

UPDATE: I've added size logging to the Tile.m:

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    NSLog(@"%s %@", __PRETTY_FUNCTION__, NSStringFromCGSize(self.frame.size));

    [_smallImage setHidden:YES];
    [_smallLetter setHidden:YES];
    [_smallValue setHidden:YES];

    [_bigImage setHidden:NO];
    [_bigLetter setHidden:NO];
    [_bigValue setHidden:NO];

    [self.superview bringSubviewToFront:self];
}

and while initially it logs the expected tile size of 45x45 (set by me in Tile.xib):

-[Tile touchesBegan:withEvent:] {45, 45}

After I rotate the device to landscape and back to portrait I suddenly get the height of 160:

-[Tile touchesBegan:withEvent:] {45, 160}
Was it helpful?

Solution

The tile becomes draggable blow its image because the view containing the tile is auto-resized by it's superview (controller's view) that changes its frame during rotation.

enter image description here

This behaviour can be easily avoided by setting autoresizing mask of the tile view to UIViewAutoresizingNone (by deselecting all springs and struts in Interface Builder).

enter image description here

Note the tools to debug problems with view sizing like this one:

  1. LLDB command po viewVariableOrAddress (calls description method of its parameter and prints the result).
  2. -[UIView recursiveDescription] called from LLDB by the following command: po [viewVariableOrAddress recursiveDescription]. Note that his method is private and must not be called in production code (the app will be rejected otherwise).
  3. Reveal — in a natural GUI, represents the same information that you can get at runtime in debugger console.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top