it-roy-ru.com

ios 11 UITabBar UITabBarItem вопрос позиционирования

Я построил свое приложение, используя новую бета-версию Xcode 9 для ios 11. Я обнаружил проблему с UITabBar, когда элементы распространяются через UITabBar, а заголовок выравнивается по правому краю изображения. Я попытался изменить код, чтобы заставить его работать, но все еще не успешно.

iOS 10+

enter image description here

iOS 11

enter image description here

Я мог бы изменить положение заголовка с помощью tabBarItem.titlePositionAdjustment Но это не мое требование, так как оно должно автоматически появиться ниже самого изображения. Я попытался установить tabbar.itemPositioning to UITabBarItemPositioningCentered, а также попытался изменить itemSpacing и width, но все равно не сработало. Может кто-нибудь помочь мне понять, почему это происходит и как это исправить? Я хочу, чтобы понравилась версия ios 10+, а изображения взяты из самого левого угла iPad.

44
Gihan

Я поддерживаю большое приложение для iPad, написанное в основном на Objective-C, которое пережило несколько выпусков iOS. Я столкнулся с ситуацией, когда мне потребовалось появление панели вкладок до iOS 11 (с иконками над заголовками, а не рядом с ними) для пары панелей вкладок. Мое решение состояло в том, чтобы создать подкласс UITabBar, который переопределяет метод traitCollection, чтобы он всегда возвращал горизонтально-компактную коллекцию признаков. Это заставляет iOS 11 отображать заголовки под значками для всех кнопок панели вкладок.

Чтобы использовать это, установите пользовательский класс панелей вкладок в раскадровке для этого нового подкласса и измените любые выходы в коде, которые указывают на панели вкладок, для этого нового типа (не забудьте импортировать файл заголовка ниже).

В этом случае файл .h практически пуст:

//
//  MyTabBar.h
//

#import <UIKit/UIKit.h>

@interface MyTabBar : UITabBar

@end

Вот файл .m с реализацией метода traitCollection:

//
//  MyTabBar.m
//

#import "MyTabBar.h"

@implementation MyTabBar

// In iOS 11, UITabBarItem's have the title to the right of the icon in horizontally regular environments
// (i.e. the iPad).  In order to keep the title below the icon, it was necessary to subclass UITabBar and override
// traitCollection to make it horizontally compact.

- (UITraitCollection *)traitCollection {
    return [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
}

@end
38
John C.

Основываясь на ответе Джона С., вот версия Swift 3, которая может использоваться программно без необходимости раскадровки или создания подклассов:

extension UITabBar {
    // Workaround for iOS 11's new UITabBar behavior where on iPad, the UITabBar inside
    // the Master view controller shows the UITabBarItem icon next to the text
    override open var traitCollection: UITraitCollection {
        if UIDevice.current.userInterfaceIdiom == .pad {
            return UITraitCollection(horizontalSizeClass: .compact)
        }
        return super.traitCollection
    }
}
32
massimobio

Чтобы не испортить какие-либо другие черты, не лучше ли сочетать их с суперклассами:

- (UITraitCollection *)traitCollection
{
  UITraitCollection *curr = [super traitCollection];
  UITraitCollection *compact = [UITraitCollection  traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];

  return [UITraitCollection traitCollectionWithTraitsFromCollections:@[curr, compact]];
}
17
Andy C

ПРИМЕЧАНИЕ: Это исправление выше , кажется, работает довольно хорошо. Не уверен, как это будет работать в будущем, но сейчас это работает довольно хорошо.


Согласно этот доклад WWDC , это новое поведение для:

  • iPhone в ландшафте
  • iPad все время

И если я правильно читаю, это поведение нельзя изменить:

У нас есть совершенно новый внешний вид для панели вкладок, как в альбомной ориентации, так и на iPad, где мы показываем значок и текст рядом. И, в частности, на iPhone значок меньше, а панель вкладок меньше, чтобы обеспечить немного больше места по вертикали.

14
Dan Rosenstark

Версия Swift 4 с подклассом, который позволяет избежать коллизии имен расширения/категории:

class TabBar: UITabBar {
  override var traitCollection: UITraitCollection {
    guard UIDevice.current.userInterfaceIdiom == .pad else {
      return super.traitCollection
    }

    return UITraitCollection(horizontalSizeClass: .compact)
  }
}

Если вы используете Interface Builder и раскадровки, вы можете выбрать представление панели вкладок в сцене UITabBarController и изменить его класс на TabBar в Identity Inspector:

enter image description here

10
Max Desiatov

В дополнение к ответу Джона:

Если у вас более 4 элементов панели вкладок и вам не нужна кнопка "Дополнительно", вам нужно выбрать другой класс размера. И если вы хотите оригинальную центрированную компоновку элементов, вам нужно добавить другой метод, например, так:

#import "PreIOS11TabBarController.h"

@interface PreIOS11TabBarController ()

@end

@implementation PreIOS11TabBarController

// In iOS 11, UITabBarItem's have the title to the right of the icon in horizontally regular environments
// (i.e. the iPad).  In order to keep the title below the icon, it was necessary to subclass UITabBar and override
// traitCollection to make it horizontally compact.

- (UITraitCollection *)traitCollection {
    return [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
}


- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    self.tabBar.itemPositioning = UITabBarItemPositioningCentered;
}

@end
2
twofish