web-dev-qa-db-ja.com

xcode 11ベータ版のこの新しいナビゲーションバーの動作はバグですか、それとも意図されたものですか?

Xcode 11ベータ版でアプリをコンパイルした後、prefersLargeTitlesが設定されているとナビゲーションバーに背景がないことに気付きました。これは意図された動作ですか?

これは、下にスクロールしたときにメッセージアプリがどのように機能し、ナビゲーションバーの背景がない大きなタイトルが表示されていることに気づきました。

navBar属性を設定するために使用されるコードは次のとおりです。

 override func viewWillAppear(_ animated: Bool) {
    let textAttributes = [NSAttributedString.Key.foregroundColor:ThemeManager.shared.default1]
    self.navigationController?.navigationBar.largeTitleTextAttributes = textAttributes
    self.navigationController?.navigationBar.titleTextAttributes = textAttributes
    self.navigationController?.navigationBar.tintColor = ThemeManager.shared.default1
 self.navigationController?.setNavigationBarHidden(false, animated: true)
    self.navigationController?.navigationBar.prefersLargeTitles = true
    let nav = self.navigationItem
    nav.title = "My Profile"
}

違いを示すいくつかの画像を次に示します。

左、Xcode 10でコンパイル、右、Xcode 11ベータ:

enter image description hereenter image description here

11ベータ版を上にスクロールすると、背景がフェードインします。Xcode11ベータでコンパイルされていないアプリは通常の方法で動作しますが、何らかの理由でコンパイルした後にのみ変更されます。これは意図されたものであり、元の動作に戻すにはどうすればよいですか?

9
Peter Ruppert

これはiOS 13向けの動作です。

Appleの考え(私の考えではひどい)は、タイトルがコンテンツと結合して、関連していることを示す必要があるというものです。スクロールを開始すると、コンテンツがタイトルバーの後ろにくると、タイトルバーは「正しい」外観になります。

これがひどい理由は、誰もがこの動作なしですべてのUIを現在計画しているためです。したがって、新しい動作はすべてのユーザーにオプトアウトを強制するのではなく、オプトインにする必要があります(つまり、変更によりすべてのユーザーのコードが破損し、少なくともすべてのユーザーのコードを破損する場合は、試行された真の動作を維持する方法について明確にする必要があります過去10年間)。

あなたの場合のように、結果は恐ろしく見えます。私の場合も結果は恐ろしいようです。

アップルは答えを出しませんが、あなたが使うべきだと言います

- scrollEdgeAppearance

UINavigationBarから、コンテンツがコンテンツの最上部と最下部のナビゲーションバーに揃えられたときのバーの外観を制御するために...私の場合、このメソッドはnilを返すので、現在どのように使用するべきかわからないこの。

これもここで議論されているようです:

iOS 13のUISplitViewControllerの詳細ペインの新しいUINavigationBarの外観

したがって、現在の回避策はView Controllerではこれのようです:

- (void)viewDidLoad;
{
    [super viewDidLoad];
    if (@available(iOS 13,*)){
        UINavigationBar *bar =self.navigationController.navigationBar;
        bar.scrollEdgeAppearance = bar.standardAppearance;
    }
}

それは機能しますが、意図したアプローチであるかどうかはわかりません...

編集:

これを行うと、前述のように、UINavigationBarへの追加の直接カスタマイズがブロックされるようです。ここからscrollEdgeAppearanceを調整する方法が考えられます。醜い。醜い。醜い。

編集:進行状況...これは、背景を管理するために現在機能しています。 barTintを直接設定する代わりに、これを呼び出す必要があります。

@interface UINavigationBar (Compatibility)
- (void)setCompatibleTint:(UIColor *)fg andBarTint:(UIColor *)bg;
@end

@implementation UINavigationBar (Compatibility)
- (void)setCompatibleTint:(UIColor *)fg andBarTint:(UIColor *)bg;
{
    self.tintColor = fg;
    self.barTintColor = bg;
    if (@available(iOS 13,*)){
        // we need to tell it to adopt old style behavior first
        UINavigationBarAppearance *appearance = self.standardAppearance;
        appearance.backgroundColor = bg;
        NSDictionary *attributes = self.titleTextAttributes;
        appearance.titleTextAttributes = attributes;
        attributes = self.largeTitleTextAttributes;
        appearance.largeTitleTextAttributes = attributes;
        self.scrollEdgeAppearance = appearance;
        self.standardAppearance = appearance;
        self.compactAppearance = appearance;
    }
}
@end

テキスト属性についてはまだ完全にはわかりませんが、背景色から流れているようです。完全なPITAです。

これをサブクラスとして設定し、barTintをオーバーライドする方が適切ですが、もちろん、多くのUIKitオブジェクトがこれらのバーを自分で作成するため、サブクラスを取得できません。

11
dbquarrel

DbquarrelのソリューションのSwiftバージョン。

まず、textAttributesを宣言します。

_let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.red]
_

これらをUINavigationBarAppearance()で使用すると、3つの異なるモード(scollEdge、標準、コンパクト)でテキストの色を変更できます。

_override func viewDidLoad() {
    super.viewDidLoad()
    if #available(iOS 13.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.largeTitleTextAttributes = textAttributes
        appearance.titleTextAttributes = textAttributes
        let bar = self.navigationController?.navigationBar
        bar?.scrollEdgeAppearance = appearance
        bar?.standardAppearance = appearance
        bar?.compactAppearance = appearance
    } else {
        // Fallback on earlier versions
    }
}
_
7
Peter Ruppert