Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPad UIModalPresentationFormSheet with UITabBarController's moreNavigationController edit mode issue

This is seemingly a bug, but i'm wondering if anyone can think of a workaround.

On iPad, you present a view controller as a UIModalPresentationFormSheet. This view controller is extending UITabBarController and has enough controllers to automatically display the "more" tab bar button. Once you tap on the more button it will display the list correctly, but as soon as you tap on 'edit' it presents the edit view larger then the actual form sheet (cropped inside the form sheet), causing the content to be out of view, including the toolbar with the "done" button. The only way to dismiss is to force quit the app.

To verify that it's not something specific to my app I started a single view project, and presented a simple modal view. This modal view controller extends UITabBarController and has the following init method:

- (id)init {
    self = [super init];
    if (self) {
        self.modalPresentationStyle = UIModalPresentationFormSheet;
        NSMutableArray *controllers = [NSMutableArray array];
        for (int i = 0; i< 15; i++) {
            UIViewController *vc = [[UIViewController alloc] init];
            UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
            vc.title = [NSString stringWithFormat:@"view %i", i];
            [controllers addObject:nav];
        }
        self.viewControllers = controllers;
    }
    return self;
}

I also tried adding the modalPresentationStyle to moreNavigationController with no change.

like image 291
dizy Avatar asked Sep 05 '12 18:09

dizy


1 Answers

Good day, dizy.

A nice challenge you've made. Here is a solution, maybe it's a bit hardcore, but it works.

I've done as you wrote – subclassed UITabBarController and presented it as a modal view controller. And run into the same problem. When tapping "edit" button in "More" screen UITabBarCustomizeView appears and it's frame is inadequate.

So I've done the following. I've made MyModalTabBarVC a delegate of itself and implemented tabBarController:willBeginCustomizingViewControllers: method:

- (void)tabBarController:(UITabBarController *)tabBarController     
willBeginCustomizingViewControllers:(NSArray *)viewControllers
{
    UIView *modalView = self.view;
    CGRect bounds = modalView.bounds;

    UIView *customizationView   = [[modalView subviews] objectAtIndex:1];
    UIView *customizationNavBar = [[customizationView subviews] objectAtIndex:0];

    CGRect navBarFrame = [customizationNavBar frame];
    navBarFrame.size.width = bounds.size.width;
    customizationNavBar.frame = navBarFrame;
    customizationView.frame   = bounds;
}

So when this method is called UITabBarCustomizeView is already created. And a wrong frame can be changed manually. If you log po [self.view subviews] at the start you'll get:

(id) $1 = 0x06c6a940 <__NSArrayM 0x6c6a940>(
<UITransitionView: 0xd744ab0; frame = (0 0; 540 571); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0xd744b50>>,
<UITabBarCustomizeView: 0x6c5e570; frame = (0 -384; 768 1004); animations = { position=<CABasicAnimation: 0x6c569a0>; }; layer = <CALayer: 0x6c618d0>>,
<UITabBar: 0xd744110; frame = (0 571; 540 49); autoresize = W+TM; layer = <CALayer: 0xd742b80>>,
)

PS. This solution doesn't fix animation. As you can see from log, corrupted animation is already created and charged. I hope that canceling it and adding a new one, appropriate, will not be a problem.

like image 168
Zapko Avatar answered Jan 04 '23 07:01

Zapko