从头开始构建tabbar视图控制器

时间:2011-06-17 10:41:44

标签: iphone ios view uitabbarcontroller orientation

Apple的标签栏控制器有很多限制。一个重要的限制是您无法在拒绝安全模式下修改标签栏。我的标签栏有一个简单的滑动动作,它是多排。 出于这些原因,我决定从一开始就建立一个TBVC;一切似乎都正常工作,但我真的搞乱旋转。每次我改变方向主视图帧都会改变。

以下是从顶部到容器视图的层次结构: -MainView - 包含 - > TabBarView + containerView containerView是用于包含从其他控制器加载的视图的视图。 这是我的CustomTabBaViewController的

- (void)loadView
{
    UIView *theView=[[UIView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
    theView.autoresizingMask=UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    theView.backgroundColor=[UIColor greenColor];

    containerOfControllersView=[[UIView alloc] initWithFrame:theView.bounds];
    containerOfControllersView.backgroundColor=[UIColor blueColor];
    containerOfControllersView.autoresizingMask=UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    [theView addSubview:containerOfControllersView];

    ideoloTabBar=[[IdeoloTabBar alloc]initWithNumberOfControllers:[controllers count]];
    [theView addSubview:ideoloTabBar];
    self.view=theView;
    [theView release];

}

当我从另一个控制器设置新视图时,我使用此方法:

-(void)setCurrentViewWithView:(UIView*)theView{
    if ([[self.containerOfControllersView subviews] count]>0) {
        UIView *tagView=[self.containerOfControllersView viewWithTag:555];
        tagView.tag=0;
        [tagView removeFromSuperview];
    }
    theView.tag=555;
    theView.autoresizingMask=UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    theView.frame=[[UIScreen mainScreen]applicationFrame];
    [self.containerOfControllersView addSubview:theView];
    [self.view bringSubviewToFront:ideoloTabBar];
}

正如您所见,使用applicationFrame应用了其他视图控制器的视图。

当我旋转设备发生错误时,主视图不仅根据新方向调整大小,而且还移动了20px(状态栏大小)到按钮,从而在状态栏和容器视图之间留下间隙。由于我给了主视图我无法理解的屏幕界限应该被移动。

更新

我正在尝试不同的方法,所以我修改了loadView:

- (void)loadView
{
    [super loadView];
    containerOfControllersView=[[UIView alloc] initWithFrame:self.view.bounds];
    containerOfControllersView.backgroundColor=[UIColor blueColor];
    containerOfControllersView.autoresizingMask=UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    self.view.backgroundColor=[UIColor greenColor];
    [self.view addSubview:containerOfControllersView];
    ideoloTabBar=[[IdeoloTabBar alloc]initWithNumberOfControllers:[controllers count]];
    [self.view addSubview:ideoloTabBar];
}

在setCurrentViewWithView:(UIView *)theView中我用

修改了这一行
theView.frame=self.view.bounds;

而不是使用applicationFrame。

NOW:

在iPhone上尝试加载modalView时,它在底部切割大约40px 在iPad上,当我尝试加载modalView时,它在底部留下了20px,因为20px位于状态栏下,但wantFullScreen为NO。

更新2

似乎应该从根视图控制器调用presentModalViewController。我将创建一个协议和一个抽象的UIViewController子类来实现它正确加载它。

有什么建议吗?解决?

3 个答案:

答案 0 :(得分:1)

我不喜欢从头开始创建完全自定义的TabBarController的方法。我喜欢将自定义视图放在真正的TabBar之上作为子视图,然后将所有按钮按下传递给真正的TabBarController。这样您就不必自己编写窗口管理器代码了。

- (void)tabButtonPressed:(id)sender
{
    UIButton *button = (UIButton *)sender;

    if (button.tag == HomeButton)
        self.tabBarController.selectedIndex = 0;

    // etc.
}

这也应该是拒绝安全的。

答案 1 :(得分:0)

这已在此处解决:Application frame leaves blank line at the top

但是,您也可以通过从y减去20来指定您的框架:

CGRect rect = [[UIScreen mainScreen] applicationFrame];
theView.frame = CGRectMake(rect.origin.x, rect.origin.y - 20, rect.size.width, rect.size.height);

答案 2 :(得分:0)

已经有一段时间了,因为我正在使用我的自定义TabBarViewController和消失的tabbar,它似乎在iPad和iPhone上都能正常工作。 我遇到的主要问题是由于对内容视图框的分配不正确,可能是因为从当前视图控制器加载了modalVC的错误假设。
第一点:内容视图应该使用主视图的边界,这里是根视图控制器的loadView方法的一部分:

[super loadView];
containerOfControllersView=[[UIView alloc] initWithFrame:self.view.bounds];


第二:在添加为子视图之前,视图控制器的视图注释它的框架应该具有与其新父视图相同的边界。

    theView.frame =self.view.bounds;

第三:模态视图控制器应该从根视图控制器加载,否则永远不会有正确的大小。这就是为什么我为每个视图控制器实现了一个基本抽象类,它继承了一个管理模态视图控制器预置和解除的协议。
希望这有助于其他人 安德烈