简单的问题,如何删除标签栏项目文本并仅显示图像?
我想要在Instagram应用中喜欢的酒吧项目:
在xcode 6中的检查器中,我删除标题并选择@ 2x(50px)和@ 3x(75px)图像。但是,图像不使用已删除文本的可用空间。任何想法如何实现相同的标签栏项目图像,如在instagram应用程序?
你应该玩imageInsets
的UITabBarItem
属性。这是示例代码:
let tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "more")
tabBarItem.imageInsets = UIEdgeInsets(top: 9, left: 0, bottom: -9, right: 0)
UIEdgeInsets
中的值取决于您的图像大小。这是我的应用程序中的代码的结果:
Swift中一个最小的,安全的UITabBarController扩展(基于@ korgx9答案):
extension UITabBarController {
func removeTabbarItemsText() {
tabBar.items?.forEach {
$0.title = ""
$0.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
中,这样它会影响应用程序整个生命周期中的所有标签栏按钮。
基于answer of 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)
}
}
}
最简单的方式,始终有效:
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
}
}
}
}
}
}
在我的例子中,在TabBar和其他导航流程中使用了相同的ViewController。在我的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)
})
// 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 design guideline
这意味着@ 1x应该有25px x 25px,@ 2x应该是50px x 50px,@ 3x应该是75px x 75px
如果在视图控制器UITabBarItem
设置中,使用方法将每个title
s ""
属性设置为imageInsets
并更新self.title
将无法正常工作。例如,如果UITabBarController的self.viewControllers
嵌入在UINavigationController
中,并且您需要在导航栏上显示标题。在这种情况下,使用UINavigationItem
直接设置self.navigationItem.title
s标题,而不是self.title
。
Swift版本的ddiego回答
与iOS 11兼容
在设置viewController的标题后,在viewControllers的每个第一个子节点的viewDidLoad中调用此函数
最佳实践:
可选择@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);
}
}
}
如果你正在使用故事板,这将是你最好的选择。它遍历所有标签栏项目,并且每个项目标题都设置为空,并使图像全屏显示。 (您必须在故事板中添加图像)
for tabBarItem in tabBar.items!
{
tabBarItem.title = ""
tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
}
iOS 11在许多这些解决方案中都存在问题,所以我只是通过继承UITabBar并覆盖layoutSubviews来修复iOS 11上的问题。
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 +“_ select”。
// 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并对其进行一些格式化的函数来完成这个技巧。
稍微向下移动图像以使其更加居中,并隐藏选项卡栏的文本。比将其标题设置为空字符串更好,因为当你有一个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中使用它:
tabBarItem.setImageOnly()