Proste pytanie, jak mogę usunąć tekst elementu paska kart i wyświetlić tylko obraz?
Chcę, aby elementy paska polubiły w aplikacji Instagram:
W inspektorze w xcode 6 usuwam tytuł i wybieram obraz @ 2x (50px) i @ 3x (75px). Jednak obraz nie wykorzystuje wolnego miejsca usuniętego tekstu. Jakieś pomysły, jak osiągnąć taki sam obraz elementu paska kart, jak w aplikacji Instagram?
ios
swift
uitabbaritem
Głosuj za
źródło
źródło
""
tytułu?Odpowiedzi:
Powinieneś bawić się
imageInsets
właściwościąUITabBarItem
. Oto przykładowy kod:let tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "more") tabBarItem.imageInsets = UIEdgeInsets(top: 9, left: 0, bottom: -9, right: 0)
Wartości wewnątrz
UIEdgeInsets
zależą od rozmiaru obrazu. Oto wynik tego kodu w mojej aplikacji:źródło
// 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); }
źródło
Oto, jak to zrobić w scenorysie.
Wyczyść tekst tytułu i ustaw wstawkę obrazu jak na poniższym zrzucie ekranu
Pamiętaj, że rozmiar ikony powinien być zgodny z wytycznymi dotyczącymi projektowania jabłek
Oznacza to, że powinieneś mieć 25 pikseli x 25 pikseli dla @ 1x, 50 pikseli x 50 pikseli dla @ 2x, 75 pikseli x 75 pikseli dla @ 3x
źródło
Użycie podejścia z ustawieniem każdej właściwości
UITabBarItem
stitle
na""
i aktualizacjiimageInsets
nie będzie działać poprawnie, jeśli w widoku kontrolerself.title
jest ustawiony. Na przykład, jeśliself.viewControllers
UITabBarController są osadzoneUINavigationController
i chcesz, aby tytuł był wyświetlany na pasku nawigacyjnym. W tym przypadku ustawUINavigationItem
tytuł bezpośrednio, używającself.navigationItem.title
, nieself.title
.źródło
Szybka wersja odpowiedzi ddiego
Zgodny z iOS 11
Wywołaj tę funkcję w viewDidLoad każdego pierwszego dziecka elementu viewControllers po ustawieniu tytułu elementu viewController
Najlepsze praktyki:
Alternatywnie, jak sugerował @daspianist w komentarzach
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) } } }
źródło
class BaseTabBarController: UITabBarController, UITabBarControllerDelegate
i umieścić tę funkcję w podklasieviewDidLoad
Jeśli używasz scenorysów, będzie to najlepsza opcja. Przechodzi przez wszystkie elementy paska kart i dla każdego ustawia tytuł na zero i wyświetla obraz na pełnym ekranie. (Musisz dodać obraz w serii ujęć)
for tabBarItem in tabBar.items! { tabBarItem.title = "" tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0) }
źródło
iOS 11 rzuca załamanie w wielu z tych rozwiązań, więc właśnie naprawiłem swoje problemy w iOS 11, podklasując UITabBar i nadpisując 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 } } }
źródło
Użyłem następującego kodu w widokuDidLoad mojego BaseTabBarControllera. Zauważ, że w moim przykładzie mam 5 zakładek, a wybrany obraz zawsze będzie 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) }
źródło
for var i = 0; i < tabBar...
, mógłbyś po prostu powiedzieć;for tabBarItems in tabBar.items!
Szybkie podejście 4
Udało mi się załatwić sprawę, implementując funkcję, która pobiera TabBarItem i formatuje ją.
Przesuwa obraz nieco w dół, aby był bardziej wyśrodkowany, a także ukrywa tekst paska kart. Działało lepiej niż tylko ustawienie tytułu na pusty ciąg, ponieważ gdy masz również NavigationBar, TabBar odzyskuje tytuł viewController po wybraniu
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) }
Najnowsza składnia
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) } }
I po prostu użyj go w swoim tabBar jako:
źródło
Oto lepszy, bardziej niezawodny sposób na zrobienie tego, inny niż najlepsza odpowiedź:
[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal]; [[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateHighlighted];
Umieść to w swoim
AppDelegate.didFinishLaunchingWithOptions
, aby miało wpływ na wszystkie przyciski paska kart przez cały okres użytkowania aplikacji.źródło
Minimalne, bezpieczne rozszerzenie UITabBarController w Swift (oparte na odpowiedzi @ korgx9):
extension UITabBarController { func removeTabbarItemsText() { tabBar.items?.forEach { $0.title = "" $0.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0) } } }
źródło
Na podstawie odpowiedzi ddiego w 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) } } }
Wystarczy wywołać
self.tabBarController?.cleanTitles()
kontroler widoku.źródło
Opierając się na wszystkich świetnych odpowiedziach na tej stronie, stworzyłem kolejne rozwiązanie, które pozwala również ponownie wyświetlić tytuł. Zamiast usuwać treść tytułu, po prostu zmieniam kolor czcionki na przezroczysty.
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) } } }
źródło
kod:
private func removeText() { if let items = yourTabBarVC?.tabBar.items { for item in items { item.title = "" } } }
źródło
Najłatwiejszy sposób i zawsze działa:
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 } } } } } }
źródło
W moim przypadku ten sam ViewController został użyty w TabBar i innym przepływie nawigacji. W moim ViewController ustawiłem,
self.title = "Some Title"
który pojawiał się w TabBar niezależnie od ustawienia tytułunil
lub pustego podczas dodawania go na pasku kart. Ustawiłem równieżimageInsets
:item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
Więc w moim ViewController, obsłużyłem tytuł nawigacji w następujący sposób:
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" }
źródło
stwórz podklasę UITabBarController i przypisz ją do swojego tabBar, a następnie w metodzie viewDidLoad umieść ten wiersz kodu:
tabBar.items?.forEach({ (item) in item.imageInsets = UIEdgeInsets.init(top: 8, left: 0, bottom: -8, right: 0) })
źródło
Niestandardowy pasek zakładek - iOS 13, Swift 5, XCode 11
Oparte na scenorysie. Można to również łatwo osiągnąć programowo. Tylko 4 kroki do wykonania:
Ikony paska kart muszą mieć 3 rozmiary, w kolorze czarnym. Zwykle pobieram z fa2png.io - rozmiary: 25x25, 50x50, 75x75. Pliki graficzne PDF nie działają!
W serii ujęć dla elementu paska kart ustaw ikonę, której chcesz użyć, za pośrednictwem Inspektora atrybutów. (patrz zrzut ekranu)
UITabBarController, klasa
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) }
}
Wynik
źródło
Jeśli chcesz wyśrodkować zakładki / zmienić wstawki obrazu bez używania magicznych liczb, zadziałało dla mnie (w Swift 5.2.2):
W podklasie UITabBarController można dodać wstawki obrazu po ustawieniu kontrolerów widoku.
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) } }
Kilka z powyższych opcji zawiera listę rozwiązań radzenia sobie z ukrywaniem tekstu.
źródło