iPhone: Как я могу создать свой собственный TabBar? - PullRequest
4 голосов
/ 06 февраля 2011

Поскольку у меня есть некоторые требования к панели вкладок, которые не может обеспечить обычная панель вкладок iphone, мне нужно создать свою собственную.

Каков наилучший способ создания собственной панели вкладок, в частности, как добавить /удалить (показать / скрыть) представления в моем главном контроллере представления правильным образом, принимая во внимание память и лучшие практики для подпредставлений?

Ответы [ 3 ]

7 голосов
/ 06 февраля 2011

Как я уже говорил в другом месте, почти никогда хорошая идея, чтобы избавиться от основных навигационных классов, предоставляемых UIKit.Какой тип требований к приложениям у вас, по вашему мнению, заслуживает полностью настраиваемого класса панели вкладок?Почти всегда можно добиться необходимых настроек путем создания подклассов, категоризации или использования слоев.

ОБНОВЛЕНИЕ 1 : Итак, вот что я сделал в некоторых из моих приложений, чтобы получить пользовательскийРеализация панели вкладок.

  1. Создайте подкласс из UITabBar
  2. Добавьте метод к вашему пользовательскому подклассу, который называется что-то вроде -updateTabBarImageForViewControllerIndex:
  3. В Интерфейсном Разработчике изменитекласс панели вкладок контроллера панели вкладок для вашего пользовательского подкласса
  4. В любом классе, соответствующем делегату контроллера панели вкладок (например, делегату приложения), внедрите -tabBarController:shouldSelectViewController: и вызовите -updateTabBarImageForViewControllerIndex: на своей пользовательской вкладкеподкласс bar

По сути, вы хотите уведомлять подкласс панели вкладок каждый раз, когда контроллер панели вкладок собирается переключать контроллеры представления.Когда это произойдет, определите, какое изображение вам нужно выбрать для панели вкладок.У вас должно быть n изображений для панели вкладок, по одному для выбранного состояния каждой вкладки.Можно на самом деле сфальсифицировать реализацию UITabBarItem и просто работать с отдельными изображениями, но это немного больше работы.

// MyAppDelegate.m

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
    // Determine the index based on the selected view controller

    NSUInteger viewControllerIndex = ...;

    [(MyTabBar *)tabBarController.tabBar updateTabBarImageForViewControllerIndex:viewControllerIndex];

    return YES;
}

// MyTabBar.m

- (void)updateTabBarImageForViewControllerIndex:(NSUInteger)index
{
    // Determine the image name based on the selected view controller index

    self.selectedTabBarImage = [UIImage imageNamed:...];

    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect
{
    CGContextDrawImage(UIGraphicsGetCurrentContext(), rect, self.selectedTabBarImage.CGImage);
}

ОБНОВЛЕНИЕ 2 : Теперь, когда я думаю об этом большеВы могли бы (и должны) получить то, чего пытаетесь достичь, вообще не имея подкласса UITabBar.Импортируйте <QuartzCore/QuartzCore.h> и используйте содержимое слоя.:)

// MyAppDelegate.m

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
    // Determine the image name based on the selected view controller

    CGImageRef newTabBarImageRef = [[UIImage imageNamed:...] CGImage];
    tabBarController.tabBar.layer.contents = (id)newTabBarImageRef;

    return YES;
}
0 голосов
/ 14 октября 2011

Эти два принятых ответа ломаются в iOS5.Вместо этого я сохранил подкласс пользовательской панели вкладок и оставил без изменений только этот метод:

- (void)drawRect:(CGRect)rect
{
   CGContextDrawImage(UIGraphicsGetCurrentContext(), rect, nil);
} 

Затем в MainWindow.xib я создал пользовательское представление с изображением в качестве фона и кнопками UIB в качествеЭлементы панели вкладок.

В делегате TabController я обновляю выбранные состояния кнопок.

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
 // Determine the index based on the selected view controller

 UIButton *newBtn;

 if(viewController == homeVC) {
   ...
 }
 // Update the buttons
 newBtn.selected = YES;
 _selectedTabBtn.selected = NO;
 _selectedTabBtn = newBtn;

 return YES;
}
0 голосов
/ 06 февраля 2011

Это действительно зависит от вашего приложения.Если вы можете позволить себе хранить в памяти все контроллеры представлений, назначенные вашей панели вкладок, то вы можете использовать простой массив, в котором будут храниться все соответствующие контроллеры представлений, и отображать их с использованием индекса в этом массиве.Также неплохо создать свой собственный контроллер представления, который бы сохранял свое собственное изображение панели вкладок (и / или заголовок).И ваша вкладка будет принимать все эти значения оттуда.

Если вы не можете позволить себе столько памяти (но это не очень возможно), тогда вы можете хранить NSDictionary в массиве, а не просматривать контроллеры.И когда пользователь нажимает на элемент панели вкладок, вы просто выгружаете предыдущий контроллер представления и создаете новый с параметрами из этого словаря.Или вместо словаря вы можете использовать некоторый пользовательский контейнерный класс.

...