Удалить текст элемента панели вкладок, показать только изображение


простой вопрос, как я могу удалить текст элемента панели вкладок и показать только изображение?

Я хочу, чтобы элементы панели понравились в приложении instagram:

в инспекторе в xcode 6 я удаляю заголовок и выбираю изображение @2x (50px) и @3x (75px). Однако изображение не использует свободное пространство удаленного текста. Любые идеи, как достичь того же изображения элемента панели вкладок, как в приложении instagram?

13 68

13 ответов:

вы должны играть с imageInsets собственность UITabBarItem. Вот пример кода:

let tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "more")
tabBarItem.imageInsets = UIEdgeInsets(top: 9, left: 0, bottom: -9, right: 0)

значения внутри UIEdgeInsets зависит от размера изображения. Вот результат этого кода в моем приложении:

enter image description here

// 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);
}

вот как вы это делаете в раскадровке.

очистите текст заголовка и установите вставку изображения, как на скриншоте ниже

enter image description here

помните, что размер значка должен следовать руководство по дизайну apple

enter image description here

Это означает, что вы должны иметь 25 пикселей х 25 пикселей для @1Х, в 50px х 50 пикселей для @2х, которой 75px X, в которой 75px для @3х

Используя подход с каждого UITabBarItems title свойство "" и обновить imageInsets не будет работать должным образом, если в представлении контроллера self.title установлен. Например, если self.viewControllers из UITabBarController встроены в UINavigationController и вам нужно название, которое будет отображаться на панели навигации. В этом случае set UINavigationItems название непосредственно с помощью self.navigationItem.title, а не self.title.

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

for tabBarItem in tabBar.items!
{
   tabBarItem.title = ""
   tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
}

Swift версия из ddiego ответ

совместимость с iOS 11

вызовите эту функцию в viewDidLoad каждого первого дочернего элемента viewControllers после установки заголовка viewController

Рекомендация:

альтернативно, как @ daspianist предложил в комментариях

сделать подкласс, как этот класс BaseTabBarController: UITabBarController, UITabBarControllerDelegate и поставить эту функцию в подклассе viewDidLoad

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 = UIEdgeInsetsMake(offset, 0, -offset, 0);
        }
    }
}

прошивкой 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
        }
    }
}

я использовал следующий код в моем basetabbarcontroller viewDidLoad. Обратите внимание, что в моем примере у меня есть 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)
}

Swift 4 подход

я смог сделать трюк, реализовав функцию, которая принимает TabBarItem и делает некоторое форматирование к нему.

перемещает изображение немного вниз, чтобы сделать его более центрированным, а также скрывает текст панели вкладок. Работал лучше, чем просто установить его название в пустую строку, потому что когда у вас есть панель навигации, а также, панель вкладок возвращает название 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)
}

минимальное, безопасное расширение UITabBarController в Свифт (на основе ответа @korgx9):

extension UITabBarController {
  func removeTabbarItemsText() {
    tabBar.items?.forEach {
      .title = ""
      .imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
    }
  }
}

вот лучший, более надежный способ сделать это, кроме верхнего ответа:

[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]}
                                         forState:UIControlStateNormal];
[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]}
                                         forState:UIControlStateHighlighted];

положите это в ваш AppDelegate.didFinishLaunchingWithOptions Так что это влияет на все кнопки панели вкладок в течение всего срока службы вашего приложения.

на основе ответ ddiego, в Swift 4:

extension UITabBarController {
    func cleanTitles() {
        guard let items = self.tabBar.items else {
            return
        }
        for item in items {
            item.title = ""
            item.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
        }
    }
}

и вам просто нужно позвонить self.tabBarController?.cleanTitles() на ваш взгляд контроллера.

enter image description here

код:

private func removeText() {
    if let items = yourTabBarVC?.tabBar.items {
       for item in items {
          item.title = ""
       }
    }
 }