[英]Build a tabbar view controller from scratch
蘋果的標簽欄控制器有很多限制。 一個重要的限制是您不能在拒絕安全模式下修改標簽欄。 我的標簽欄有一個簡單的滑動動作,並且是多行的。 由於這些原因,我決定從一開始就構建TBVC。 一切似乎都可以正常工作,但是我真的很困惑。 每次更改方向時,主視圖框架都會更改。
這是我從頂部到容器視圖的層次結構:-MainView--包含-> TabBarView + containerView containerView是用於包含從其他控制器加載的視圖的視圖。 這是我的CustomTabBaViewController的-loadView方法
- (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(狀態欄大小),因此在狀態欄和容器視圖之間會留出空隙。 由於我給了mainview屏幕邊界,我無法理解它的邊界。
更新
我正在嘗試一種不同的方法,所以我像這樣修改了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。
在iPhone上,當我嘗試加載modalView時,其底部會減少約40px。在iPad上,當我嘗試加載modalView時,其底部會向左20px,因為20px位於狀態欄下方,但wantFullScreen為NO。
似乎應該從根視圖控制器調用presentModalViewController。 我將創建一個協議和一個抽象的UIViewController子類以正確實現它。
有什么建議嗎? 解決嗎?
我不喜歡從頭開始創建一個完全自定義的TabBarController的方法。 我喜歡將自定義視圖放在真實的TabBar頂部作為子視圖,然后將所有按下的按鈕傳遞給真實的TabBarController。 這樣,您不必自己編寫窗口管理器。
- (void)tabButtonPressed:(id)sender
{
UIButton *button = (UIButton *)sender;
if (button.tag == HomeButton)
self.tabBarController.selectedIndex = 0;
// etc.
}
這也應該是拒絕安全的。
此處已解決此問題: 應用程序框架在頂部保留空白行
但是,您也可以通過從y
減去20來指定幀:
CGRect rect = [[UIScreen mainScreen] applicationFrame];
theView.frame = CGRectMake(rect.origin.x, rect.origin.y - 20, rect.size.width, rect.size.height);
自從我使用我的自定義TabBarViewController以及消失的Tabbar以來已經有一段時間了,它似乎在iPad和iPhone上都能正常工作。 我遇到的主要問題是由於對內容視圖框架的分配不正確,並且可能是由於錯誤地假設從當前視圖控制器加載了modalVC。
第一點:內容視圖應使用主視圖的邊界,這是根視圖控制器的loadView方法的一部分:
[super loadView];
containerOfControllersView=[[UIView alloc] initWithFrame:self.view.bounds];
第二:在將視圖控制器的視圖添加為子視圖之前,請向其說明其框架應具有與其新父視圖相同的邊界。
theView.frame =self.view.bounds;
第三:模式視圖控制器應該從根視圖控制器加載,否則將永遠不會有正確的大小。 這就是為什么我為每個繼承視圖管理模態視圖控制器的協議的協議的視圖控制器實現了一個基礎抽象類。
希望這對其他人有幫助。
安德里亞
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.