2011-02-06 2 views
4

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

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

ответ

6

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

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

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

В принципе, вы хотите уведомлять свой подкласбу панели вкладок каждый раз, когда контроллер панели вкладок собирается переключить контроллеры представлений. Когда это произойдет, определите, какое изображение нужно выбрать для панели вкладок. У вас должно быть 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); 
} 

UPDATE 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

На самом деле, что касается UITabBar [Controller], Apple действительно не нравится, если вы подклассифицируете его. Это можно сделать, но вы часто терпите неудачу в наборе assert(), который у них есть, чтобы остановить вас. Когда я спросил об этом на форумах dev, ответ был «Roll your own». (Я так и не сделал этого, но на пути была боль и страдания.) –

+0

Нет ничего плохого в подклассе, если все, что вы собираетесь делать, это настроить стиль, переопределив '-drawRect:', например , Да, вы не хотите переопределять какие-либо методы, которые изменяют базовую логику, но нет вреда в подклассе, если вы делаете это правильно. В любом случае, я рекомендую использовать слои только в том случае, если это возможно. Никаких подклассов или категоризации не требуется. – LucasTizma

+0

Лукас. Мне нужно изменить цвет наложения и цвет текста. Из того, что я видел, это может отказать моему приложению. –

0

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

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

+0

Сохраняет ли нормальный UITabBar все виды в памяти? –

+1

Да. Из docs - (void) setViewControllers: (NSArray *) viewControllers animated: (BOOL) анимированный. Сначала вам нужно создать контроллеры представлений. – Max

+0

Вы действительно выполняете 95% работы, уже выполненной 'UIKit', создавая собственную панель вкладок (контроллер). Почему бы не просто сделать 5% работы с помощью простого подкласса или манипуляции с содержимым слоя? – LucasTizma

0

Этот двухприведенный ответ прерывается в iOS5.То, что я вместо того, чтобы было держать планку подкласса пользовательских вкладок и оставить только этот метод нетронутым:

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

Тогда в MainWindow.xib, я создал настраиваемое представление с ImageView в качестве фона и UIButtons в качестве панели вкладок Предметы.

В делегате 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

В iOS5 они позволяют настраивать вкладку, поэтому это уже не проблема. –

+0

У вас есть ссылка на новую документацию? Не удалось найти что-либо в UITabBarItem, UITabBar или UITabBarController. – oohaba

+2

Появились новые свойства backgroundImage, selectedImageTintColor, selectionIndicatorImage и tintColor. Посмотрите в документах XCode 4.2, вы увидите их в iOS 5. –

Смежные вопросы