Простой вопрос: как удалить текст элемента панели вкладок и показать только изображение?
Я хочу, чтобы элементы бара нравились в приложении Instagram:
В инспекторе в xcode 6 я удаляю заголовок и выбираю изображение @ 2x (50 пикселей) и @ 3x (75 пикселей). Однако изображение не использует свободное пространство удаленного текста. Есть идеи, как добиться того же изображения элемента панели вкладок, что и в приложении Instagram?
ios
swift
uitabbaritem
Голосовать за
источник
источник
""
для названия?Ответы:
Вы должны поиграть со
imageInsets
свойствомUITabBarItem
. Вот пример кода:let tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "more") tabBarItem.imageInsets = UIEdgeInsets(top: 9, left: 0, bottom: -9, right: 0)
Значения внутри
UIEdgeInsets
зависят от размера вашего изображения. Вот результат этого кода в моем приложении:источник
// Remove the titles and adjust the inset to account for missing title for(UITabBarItem * tabBarItem in self.tabBar.items){ tabBarItem.title = @""; tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0); }
источник
Вот как это сделать в раскадровке.
Очистите текст заголовка и установите вставку изображения, как на скриншоте ниже.
Помните, что размер значка должен соответствовать руководству по дизайну Apple.
Это означает, что у вас должно быть 25 пикселей x 25 пикселей для @ 1x, 50 пикселей x 50 пикселей для @ 2x, 75 пикселей x 75 пикселей для @ 3x
источник
Использование подхода с установкой каждого свойства
UITabBarItem
s и update не будет работать должным образом, если установлен контроллер представления. Например, если UITabBarController встроен в, и вам нужно, чтобы заголовок отображался на панели навигации. В этом случае установить заголовок напрямую , а не .title
""
imageInsets
self.title
self.viewControllers
UINavigationController
UINavigationItem
self.navigationItem.title
self.title
источник
Быстрая версия ответа ddiego
Совместим с iOS 11
Вызовите эту функцию в viewDidLoad каждого первого дочернего элемента viewController после установки заголовка viewController
Лучшая практика:
В качестве альтернативы, как @daspianist предложил в комментариях
func removeTabbarItemsText() { var offset: CGFloat = 6.0 if #available(iOS 11.0, *), traitCollection.horizontalSizeClass == .regular { offset = 0.0 } if let items = tabBar.items { for item in items { item.title = "" item.imageInsets = UIEdgeInsets(top: offset, left: 0, bottom: -offset, right: 0) } } }
источник
class BaseTabBarController: UITabBarController, UITabBarControllerDelegate
и поместить эту функцию в подклассviewDidLoad
Если вы используете раскадровки, это будет лучшим вариантом. Он перебирает все элементы панели вкладок и для каждого из них ничего не устанавливает в заголовке и делает изображение полноэкранным. (Вы должны были добавить изображение в раскадровку)
for tabBarItem in tabBar.items! { tabBarItem.title = "" tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0) }
источник
iOS 11 вносит излом во многие из этих решений, поэтому я просто исправил свои проблемы в iOS 11, создав подкласс UITabBar и переопределив layoutSubviews.
class MainTabBar: UITabBar { override func layoutSubviews() { super.layoutSubviews() // iOS 11: puts the titles to the right of image for horizontal size class regular. Only want offset when compact. // iOS 9 & 10: always puts titles under the image. Always want offset. var verticalOffset: CGFloat = 6.0 if #available(iOS 11.0, *), traitCollection.horizontalSizeClass == .regular { verticalOffset = 0.0 } let imageInset = UIEdgeInsets( top: verticalOffset, left: 0.0, bottom: -verticalOffset, right: 0.0 ) for tabBarItem in items ?? [] { tabBarItem.title = "" tabBarItem.imageInsets = imageInset } } }
источник
Я использовал следующий код в viewDidLoad моего BaseTabBarController. Обратите внимание, что в моем примере у меня 5 вкладок, и выбранное изображение всегда будет base_image + "_selected".
// Get tab bar and set base styles let tabBar = self.tabBar; tabBar.backgroundColor = UIColor.whiteColor() // Without this, images can extend off top of tab bar tabBar.clipsToBounds = true // For each tab item.. let tabBarItems = tabBar.items?.count ?? 0 for i in 0 ..< tabBarItems { let tabBarItem = tabBar.items?[i] as UITabBarItem // Adjust tab images (Like mstysf says, these values will vary) tabBarItem.imageInsets = UIEdgeInsetsMake(5, 0, -6, 0); // Let's find and set the icon's default and selected states // (use your own image names here) var imageName = "" switch (i) { case 0: imageName = "tab_item_feature_1" case 1: imageName = "tab_item_feature_2" case 2: imageName = "tab_item_feature_3" case 3: imageName = "tab_item_feature_4" case 4: imageName = "tab_item_feature_5" default: break } tabBarItem.image = UIImage(named:imageName)!.imageWithRenderingMode(.AlwaysOriginal) tabBarItem.selectedImage = UIImage(named:imageName + "_selected")!.imageWithRenderingMode(.AlwaysOriginal) }
источник
for var i = 0; i < tabBar...
вы могли бы просто сказать;for tabBarItems in tabBar.items!
Swift 4 подход
Мне удалось проделать трюк, реализовав функцию, которая принимает TabBarItem и выполняет для него некоторое форматирование.
Сдвигает изображение немного вниз, чтобы сделать его более центрированным, а также скрывает текст панели вкладок. Работает лучше, чем просто установка его заголовка на пустую строку, потому что, когда у вас также есть NavigationBar, TabBar восстанавливает заголовок viewController при выборе
func formatTabBarItem(tabBarItem: UITabBarItem){ tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0) tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:UIColor.clear], for: .selected) tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor:UIColor.clear], for: .normal) }
Последний синтаксис
extension UITabBarItem { func setImageOnly(){ imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0) setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.clear], for: .selected) setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.clear], for: .normal) } }
И просто используйте его в tabBar как:
источник
Вот лучший и более надежный способ сделать это, кроме основного ответа:
[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal]; [[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateHighlighted];
Поместите это в свой,
AppDelegate.didFinishLaunchingWithOptions
чтобы он влиял на все кнопки панели вкладок на протяжении всего жизненного цикла вашего приложения.источник
Минимальное безопасное расширение UITabBarController в Swift (на основе ответа @ korgx9):
extension UITabBarController { func removeTabbarItemsText() { tabBar.items?.forEach { $0.title = "" $0.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0) } } }
источник
Основываясь на ответе ddiego в Swift 4.2 :
extension UITabBarController { func cleanTitles() { guard let items = self.tabBar.items else { return } for item in items { item.title = "" item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0) } } }
И вам просто нужно вызвать
self.tabBarController?.cleanTitles()
свой контроллер представления.источник
Основываясь на всех замечательных ответах на этой странице, я создал другое решение, которое также позволяет вам снова отображать заголовок. Вместо удаления содержимого заголовка я просто меняю цвет шрифта на прозрачный.
extension UITabBarItem { func setTitleColorFor(normalState: UIColor, selectedState: UIColor) { self.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: normalState], for: .normal) self.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: selectedState], for: .selected) } } extension UITabBarController { func hideItemsTitle() { guard let items = self.tabBar.items else { return } for item in items { item.setTitleColorFor(normalState: UIColor(white: 0, alpha: 0), selectedState: UIColor(white: 0, alpha: 0)) item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0) } } func showItemsTitle() { guard let items = self.tabBar.items else { return } for item in items { item.setTitleColorFor(normalState: .black, selectedState: .yellow) item.imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) } } }
источник
код:
private func removeText() { if let items = yourTabBarVC?.tabBar.items { for item in items { item.title = "" } } }
источник
Самый простой способ и всегда работает:
class TabBar: UITabBar { override func layoutSubviews() { super.layoutSubviews() subviews.forEach { subview in if subview is UIControl { subview.subviews.forEach { if $0 is UILabel { $0.isHidden = true subview.frame.origin.y = $0.frame.height / 2.0 } } } } } }
источник
В моем случае тот же ViewController использовался в TabBar и другом потоке навигации. Внутри моего ViewController я установил,
self.title = "Some Title"
что отображалось в TabBar независимо от установки заголовкаnil
или пустого поля при добавлении его в панель вкладок. Я также установилimageInsets
следующее:item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
Итак, внутри моего ViewController я обработал заголовок навигации следующим образом:
if isFromTabBar { // Title for NavigationBar when ViewController is added in TabBar // NOTE: Do not set self.title = "Some Title" here as it will set title of tabBarItem self.navigationItem.title = "Some Title" } else { // Title for NavigationBar when ViewController is opened from navigation flow self.title = "Some Title" }
источник
создайте подкласс UITabBarController и назначьте его своему tabBar, затем в методе viewDidLoad поместите эту строку кода:
tabBar.items?.forEach({ (item) in item.imageInsets = UIEdgeInsets.init(top: 8, left: 0, bottom: -8, right: 0) })
источник
Пользовательская панель вкладок - iOS 13, Swift 5, XCode 11
Раскадровка на основе. Этого можно легко достичь и программно. Всего 4 шага, которым нужно следовать:
Значки панели вкладок должны быть трех размеров черного цвета. Обычно качаю с fa2png.io - размеры: 25x25, 50x50, 75x75. Файлы изображений PDF не работают!
В раскадровке для элемента панели вкладок установите значок, который вы хотите использовать, с помощью инспектора атрибутов. (см. скриншот)
UITabBarController класс
class RoundedTabBarViewController: UITabBarController {
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. // Custom tab bar view customizeTabBarView() } private func customizeTabBarView() { let tabBarHeight = tabBar.frame.size.height self.tabBar.layer.masksToBounds = true self.tabBar.isTranslucent = true self.tabBar.barStyle = .default self.tabBar.layer.cornerRadius = tabBarHeight/2 self.tabBar.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner] } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let viewWidth = self.view.bounds.width let leadingTrailingSpace = viewWidth * 0.05 tabBar.frame = CGRect(x: leadingTrailingSpace, y: 200, width: viewWidth - (2 * leadingTrailingSpace), height: 49) }
}
Результат
источник
Если вы хотите центрировать вкладки / изменить вставки изображений без использования магических чисел, у меня сработало следующее (в Swift 5.2.2):
В подклассе UITabBarController вы можете добавить вставки изображений после установки контроллеров представления.
override var viewControllers: [UIViewController]? { didSet { addImageInsets() } } func addImageInsets() { let tabBarHeight = tabBar.frame.height for item in tabBar.items ?? [] where item.image != nil { let imageHeight = item.image?.size.height ?? 0 let inset = CGFloat(Int((tabBarHeight - imageHeight) / 4)) item.imageInsets = UIEdgeInsets(top: inset, left: 0, bottom: -inset, right: 0) } }
В некоторых из приведенных выше вариантов перечислены решения, позволяющие скрыть текст.
источник