iOS7 - Setting selectedIndex of UITabBarController breaks touch events along right-hand edge of screen?

后端 未结 5 1827
逝去的感伤
逝去的感伤 2020-12-15 22:08

I\'ve hit a weird problem with UITabBarController on iOS7 and can\'t seem to find a workaround, so any help would be welcome!

Scenario:

相关标签:
5条回答
  • 2020-12-15 22:51

    Right answer don't worked for me, cause user can change orientation; And it still not touchable in some area when change orientation.

    So I create my own solution, I don't sure that is normal solution.

    @implementation FixedIOS7TabBarController
    - (UIView*)findInSubview:(UIView*)view className:(NSString*)className
    {
        for(UIView* v in view.subviews){
            if([NSStringFromClass(v.class) isEqualToString:className])
                return v;
            UIView* finded = [self findInSubview:v className:className];
            if(finded)
                return finded;
        }
        return nil;
    }
    
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        UIView* wraperView = [self findInSubview:self.view className:@"UIViewControllerWrapperView"];
        wraperView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    }
    @end
    

    Works perfectly for me!

    0 讨论(0)
  • 2020-12-15 22:52

    I ended up raising this with Developer Tech Support, and it looks like a bug. This is the response I got back from Apple:

    The container view that the tab bar controller sets up to contain your view controller is not being resized to account for the interface being in landscape orientation. It's dimensions at the time your view controller is displayed are 768 (width) x 1024 (height).

    The view hierarchy looks like this when the selected tab's view is displayed:

    UIWindow
        /* Navigation Controller */
        UILayoutContainerView
            UINavigationTransitionView
                UIViewControllerWrapperView
                    /* Tab bar controller */
                    UILayoutContainerView
                        UITransitionView
                            UIViewControllerWrapperView <-- Incorrectly sized.
                                /* MyViewController */
                                MyViewController.view
    

    The incorrect size of UIViewControllerWrapperView does not cause a display problem because subviews are still displayed even if they are outside their superview's bounds. However, event routing is much more strict. Events on the right quarter of the screen are never routed to your view controller's view because the hit test fails at the wrongly-sized UIViewControllerWrapperView where the event falls outside UIViewControllerWrapperView's bounds.

    As a workaround, I subclassed UITabBarController, and added the following in viewWillAppear:

    @implementation FixedIOS7TabBarController
    
    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        // Fix the frame of the UIViewControllerWrapperView
        self.selectedViewController.view.superview.frame = self.view.bounds;
    }
    
    @end
    

    Hope that helps someone else....

    0 讨论(0)
  • 2020-12-15 22:53

    End up finding a workaround here:

    self.view.autoresizesSubviews = YES;
    self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    
    0 讨论(0)
  • 2020-12-15 22:59

    As explained in this answer,

    The container view that the tab bar controller sets up to contain your view controller is not being resized to account for the interface being in landscape orientation. Its dimensions at the time your view controller is displayed are 768 (width) x 1024 (height).

    I was encountering this problem when the TabBarController was originally displayed in portrait mode. When the device was rotated into landscape mode, the view was unresponsive on the right hand side.

    The solution proposed in that answer did not work for me, because viewWillAppear: is invoked only once. However, viewDidLayoutSubvews is invoked whenever the view changes, including rotations, so my solution was to subclass UITabBarController and perform the workaround in viewDidLayoutSubvews:

    @implementation FixedIOS7TabBarController
    
    - (void)viewDidLayoutSubviews
    {
        // fix for iOS7 bug in UITabBarController
        self.selectedViewController.view.superview.frame = self.view.bounds;
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-15 23:04

    In the list of view controllers on the left hand side navigate to the views/view controllers affected, drag the view to underneath the first responder so that it is disassociated to the view controller's view.

    Then go to the layout tab on the right hand side, select all 4 anchors and both sets of resizing arrows (horizontal + vertical).

    Then drag the view back to where it was originally (just below the view controller).

    0 讨论(0)
提交回复
热议问题