自定义TabBar丢失TabBarItem图像

时间:2013-09-27 21:45:30

标签: objective-c xcode uinavigationcontroller uitabbarcontroller uitabbar

我已经制作了一个非常好的自定义UITabBar,但是我引入了导航更改,现在我遇到了一些严重的问题。这就是我所拥有的:

常规设置

TabBarController 
    NavbarController1 - TabBarItem1
        Links to: PeopleView
    NavbarController2 - TabBarItem2
        Links to: ContentView
    NavbarController3 - TabBarItem3
        Links to: ContentView //Same VC as TabBaritem 2.  

App Delegate - 在我的didFinishLaunchingWithOptions方法中,我按如下方式调用customizeTabBar方法

-(void) customizeTabBar
{

UITabBarController *tabVC = (UITabBarController *) self.window.rootViewController;
//Load Navigation Bar images
NSArray *unSelectedImages = [[NSArray alloc] initWithObjects:@"image1.jpg", @"image2.jpg", @"image3.jpg", @"image4.jpg", @"image5.jpg", nil];
NSArray *selectedImages = [[NSArray alloc] initWithObjects:@"image1_on.jpg", @"image2_on.jpg", @"image3_on.jpg", @"image4_on.jpg", @"image5_on.jpg", nil];

NSArray *items = tabVC.tabBar.items;

for (int idx = 0; idx < items.count; idx++)
{

    UITabBarItem *barItem = [items objectAtIndex:idx];
    barItem.tag = idx;
    UIImage *selectedImage = [UIImage imageNamed:[selectedImages objectAtIndex:idx]];
    UIImage *unSelectedImage = [UIImage imageNamed:[unSelectedImages objectAtIndex:idx]];


    UIEdgeInsets inset = {
        .top = 10,
        .left = 0,
        .bottom = -10,
        .right = 0
    };

    barItem.imageInsets = inset;

    [barItem setFinishedSelectedImage:selectedImage withFinishedUnselectedImage:unSelectedImage];
}

到目前为止,这工作得非常好。

以下是问题所在。为了让我的TabBarItem3链接到ContentView, 我在TabBarClass中实现了以下代码:

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {

if (viewController.tabBarItem.tag == 1 || viewController.tabBarItem.tag == 2 )
{
    // Validating if is necesarry to replace the TabBarController.ViewControllers
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

    MediaList *mediaView = [storyboard  instantiateViewControllerWithIdentifier:@"SB_MediaList"];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mediaView];
    NSMutableArray *viewsArray = [NSMutableArray arrayWithArray:self.viewControllers];


    if (viewController.tabBarItem.tag == 1)
    {
        //Setting the specfic data for my instance for tabBarItem 1
        NSLog(@"Here we are in 1");
        [mediaView setContent:@"Personalized content/data for TabBarItem 1"];
    }
    else if (viewController.tabBarItem.tag == 2)
    {
        //Setting the specfic data for my instance for tabBarItem 2
        NSLog(@"Here we are in 2");
        [mediaView setContent:@"Personalized content/data for TabBarItem 2"];
    }
    [viewsArray replaceObjectAtIndex:viewController.tabBarItem.tag withObject:navigationController];
    self.viewControllers = viewsArray;

}
}

执行此代码后,我丢失了与项目2或3的自定义标签栏关联的图像(取决于我选择的图像)。

更新

所以,我将我的标签栏自定义方法移出了我的委托并进入了维护栏类,我在viewdidload上调用了它,我把它隐藏了didselectviewcontroller。这似乎解决了丢失图像的问题,但是当我点击任一软管项目时,在屏幕上产生了闪烁的副作用。我尝试过将它从viewdidload方法中删除的不同组合,但我们还没有运气..

1 个答案:

答案 0 :(得分:0)

据我所知,这一切的目的是避免为两个标签栏项目创建不同的类,这两个标签栏项目将执行几乎相同但具有不同数据的项目。

所以,你必须定义一个能够做这种事情的类,我们称之为CommonClass。该类必须具有进行正确初始化的必要方法。 [我相信你已经这样做了]。

然后在你的故事板上,你仍然需要有两个ViewController元素,每个元素作为对应NavigationController的rootViewController。

enter image description here

我强烈建议您采用这种方式,而不是按照我们尝试的方式尝试按代码分配新实例:Linking to a view multiple times from tabar。这两个视图控制器显然属于同一个类CommonClass,因此您仍将重用该类。通过这种方式,我们不必在执行时间内改变NavigationBar,这可能是混乱的。

然后,您可以为CommonClass上的CommonClass发送必要的初始化信息,该方法将根据所选的tabBarItem加载适当的信息/数据viewDidLoad,您可以在- (void)viewDidLoad { [super viewDidLoad]; if (self.tabBarController.selectedIndex == 1) { [self customizeWithData:@"Specific data for my first instance"]; } else if (self.tabBarController.selectedIndex == 2) { [self customizeWithData:@"Specific data for my second instance"]; } } 上执行此操作{1}}方法。

如下:

{{1}}

通过这种方式,您将只在代码的一部分中自定义标签栏,并且由于您不会在执行时更改它,因此您不需要在其他部分进行自定义,从而导致闪烁。