user action in uiviews buttons disabled after fram

2019-06-14 10:33发布

问题:

I do have a UIView subclass, lets call it PopupView. inside this PopupView i do have a NavigationBar with a custom uiview and a uibutton (2) inside it. Also there is a UIButton (1) directly inside the PopupView.

PopupView
  - UIButton (1)
  - UINavigationBar
    - UINavigationItem
      - UIBarButtonItem
        - UIView
          - UIButton (2)

the reason of this uibutton in uinavigationbar crazyness is because i can use capinsets for backgroundimages in a uibutton but not for a uibarbuttonitem.

My Problem:

i resize the PopupView using uiview animation and after the animation is completed, i'm unable to click the buttons in this uiview anymore.

[UIView animateWithDuration:0.4f delay:0.0f options:UIViewAnimationCurveEaseOut animations:^{
        CGRect popupFrame = self.frame;
        popupFrame.size.height += 140.0f;
        popupFrame.origin.y = floorf(popupFrame.origin.y - (140.0f / 2));
        self.frame = popupFrame;
    } completion:^(BOOL finished) {
}];

this also happens if i don't use uiview animations and set the new frame directly. also it doesn't matter if i resize it on a click or directly on viewDidLoad in it's viewController.

Any ideas why this happens?

回答1:

Heer's the relevant part of your recursiveDescription output:

|    | <UIView: 0xaac0480; frame = (0 0; 320 568); tag = 23945; layer = <CALayer: 0xaac04e0>>
|    |    | <MJPopupBackgroundView: 0xaac0710; frame = (0 0; 320 568); tag = 23943; layer = <CALayer: 0xaac07c0>>
|    |    | <UIButton: 0xaac0aa0; frame = (0 0; 320 568); opaque = NO; layer = <CALayer: 0xaac0b60>>
|    |    | <UIView: 0x9d6fea0; frame = (10 204; 300 160); autoresize = W+H; tag = 23942; layer = <CALayer: 0x9d6ff50>>
|    |    |    | <MoviePopupView: 0xab1aaa0; frame = (0 -70; 300 300); clipsToBounds = YES; layer = <CALayer: 0xab1a070>>

The 0xaac view covers the screen.

Inside the 0xaac view, the 0x9d6 view has a height of 160 points and is centered vertically within the 0xaac view.

Inside the 0x9d6 view, the 0xab1 MoviePopupView has a height of 300 points and (with its Y origin of -70) is centered “inside” the 0x9d6 view, but spills past the top and bottom edges of the 0x9d6 view.

The default value of the clipsToBounds property is NO, so the 0x9d6 view doesn't visually clip the contents of its 0xab1 subview. Thus the buttons are still visible on screen.

However, hit testing always clips to a view's bounds. So when you try to touch one of the buttons, the hit is outside the bounds of the 0x9d6 view (which only has a height of 160 points). The 0x9d6 view rejects the touch before it gets to the MoviePopupView or the buttons under it.

This is mentioned in the hitTest:withEvent: documentation:

Points that lie outside the receiver’s bounds are never reported as hits, even if they actually lie within one of the receiver’s subviews. This can occur if the current view’s clipsToBounds property is set to NO and the affected subview extends beyond the view’s bounds.



回答2:

It's impossible to say for sure since we don't see the locations of your buttons, but if you give a background color to your UIView that contains your buttons (or set it to clip subviews), you may find that the resizing is causing your buttons to be outside the frame, thereby making them unclickable.