Search code examples
objective-ciosuiviewuiview-hierarchy

UIView clipToBounds is not stopping a subView receiving touches outside the parent view


I have two UIViews. I'm using one to contain the other so that I can slide one inside the other. I'm encountering an issue where even though a subView is clipped to the bounds of its parent, it is still receiving touch events and blocking access to other underlying views.

I have three screenshots that show the layout. I've coloured the parent green and the child red.

The idea is that the user clicks "View" and the subView slides up. When the subView is in the default position, the UITabBar is covered and cannot be clicked. You can see this in the first image where the red view is present at the bottom. When the subView is moved to the top, the UITabBar can be clicked as it's now visible. In the third image, I've show what it's like with clipToBounds enabled on the green UIView.

I've enabled clipToBounds, so I cannot understand why the subView is blocking the underlying UITabBar. Is my understanding of clipToBounds completely wrong??


Solution

  • Using clipToBounds only affects the visual layout of a subView, not the logical layout. This means that whilst my subView isn't visible to the eye, it's visible to touch.

    I've worked around this issue by animating the size of the subView rather than its position. In my code below, the stationProximityView is the subView. I animate its size by 40 pixels to bring the black title back into view.

    [UIView beginAnimations:@"stationProximityBar" context:NULL];
    self.stationProximityView.view.frame = CGRectOffset(self.stationProximityView.view.frame, 0, -40);
    [UIView commitAnimations];
    

    When I no longer need it, I animate it out of view.

    [UIView beginAnimations:@"stationProximityBar" context:NULL];
    self.stationProximityView.view.frame = CGRectMake(0 ,0, 320, 500);
    [UIView commitAnimations];
    

    If the user taps the view button, the entire subView is shown:

     [UIView beginAnimations:@"stationProximityBar" context:NULL];
     self.stationProximityView.view.frame = CGRectMake(0,460,320,40);
     [UIView commitAnimations];
    

    Dismissal causes the view to be hidden in the same way as the small bar.

     [UIView beginAnimations:@"hideStationProximityBar" context:NULL];
     self.stationProximityView.view.frame = CGRectMake(0,0,320,500);
     [UIView commitAnimations];
    

    At the moment, this code is only being tested on the iPhone 5, so the hard-coded height of 500 would causes issues on previous iPhone models.