IOS 11用の新しいXcode 9ベータ版を使用してアプリを構築しました。UITabBarを介してアイテムが展開され、タイトルが画像に正しく配置されるというUITabBarの問題を発見しました。動作するようにコードを変更しようとしましたが、まだ成功していません。
iOS 10+
iOS 11
tabBarItem.titlePositionAdjustment
を使用してタイトルの位置を変更できますが、画像自体の下に自動的に表示されるため、これは私の要件ではありません。 tabbar.itemPositioning to UITabBarItemPositioningCentered
を設定しようとし、itemSpacing
とwidth
を変更しようとしましたが、まだ動作しませんでした。誰かがこれが起こる理由とこれを修正する方法を理解するのを助けることができますか? iOS 10以降のバージョンが好きで、iPadの左端から画像が撮影されます。
私は、主にObjective-Cで書かれた大規模なiPadアプリを保守していますが、これはいくつかのiOSリリースを生き延びています。いくつかのタブバーについて、iOS 11より前のタブバーの外観(タイトルの横ではなくアイコンの上に)が必要な状況に遭遇しました。私の解決策は、traitCollection
メソッドをオーバーライドするUITabBarのサブクラスを作成して、常に水平方向にコンパクトな特性コレクションを返すようにすることでした。これにより、iOS 11では、すべてのタブバーボタンのアイコンの下にタイトルが表示されます。
これを使用するには、ストーリーボードのタブバーのカスタムクラスをこの新しいサブクラスに設定し、タブバーを指すコードのアウトレットをこの新しいタイプに変更します(ヘッダーファイルのインポートを忘れないでください)未満)。
この場合、.hファイルはほとんど空です。
//
// MyTabBar.h
//
#import <UIKit/UIKit.h>
@interface MyTabBar : UITabBar
@end
traitCollection
メソッドの実装を含む.mファイルは次のとおりです。
//
// 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
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
}
}
他の特性を台無しにしないようにするには、スーパークラスと組み合わせることをお勧めします。
- (UITraitCollection *)traitCollection
{
UITraitCollection *curr = [super traitCollection];
UITraitCollection *compact = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
return [UITraitCollection traitCollectionWithTraitsFromCollections:@[curr, compact]];
}
拡張機能/カテゴリの命名の衝突を回避するサブクラスを備えた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
シーンでタブバービューを選択し、IDインスペクターでそのクラスをTabBar
に変更できます。
ジョンの答えに加えて:
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