web-dev-qa-db-ja.com

iOS 11 UITabBar UITabBarItemの配置の問題

IOS 11用の新しいXcode 9ベータ版を使用してアプリを構築しました。UITabBarを介してアイテムが展開され、タイトルが画像に正しく配置されるというUITabBarの問題を発見しました。動作するようにコードを変更しようとしましたが、まだ成功していません。

iOS 10+

enter image description here

iOS 11

enter image description here

tabBarItem.titlePositionAdjustmentを使用してタイトルの位置を変更できますが、画像自体の下に自動的に表示されるため、これは私の要件ではありません。 tabbar.itemPositioning to UITabBarItemPositioningCenteredを設定しようとし、itemSpacingwidthを変更しようとしましたが、まだ動作しませんでした。誰かがこれが起こる理由とこれを修正する方法を理解するのを助けることができますか? iOS 10以降のバージョンが好きで、iPadの左端から画像が撮影されます。

44
Gihan

私は、主に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
38
John C.

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
    }
}
33
massimobio

他の特性を台無しにしないようにするには、スーパークラスと組み合わせることをお勧めします。

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

  return [UITraitCollection traitCollectionWithTraitsFromCollections:@[curr, compact]];
}
18
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シーンでタブバービューを選択し、IDインスペクターでそのクラスをTabBarに変更できます。

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