2017-09-14 21 views
73

任何人在UITabBar組件周圍的iPhone X模擬器有問題嗎?我似乎正在渲染圖標和標題在彼此之上,我不確定是否我錯過了任何東西,我也在iPhone 8模擬器中運行它,以及它看起來不錯的一個實際設備如故事板上所示。iOS 11 iPhone X模擬器UITabBar圖標和標題正在渲染頂部覆蓋海誓山盟

iPhone X:

iPhone X UITabBar bug

iPhone 8

iPhone 8 UITabBar works

+1

我類似的問題的解決:選擇指標圖像視圖下沉在iPhone X的約16個點在tabBar視圖。 – Itachi

+0

僅供參考 - 這不幸在Xcode 9.2beta – tdios

回答

1

的UITabBar在高度上增加是主頁按鈕/線之上,但是繪製子視圖在其原始位置並在子視圖上覆蓋UITabBarItem。

作爲解決方法,您可以檢測iPhone X,然後將視圖高度縮小32px,以確保標籤欄顯示在主線上方的安全區域中。

例如,如果您建立的TabBar編程更換

self.tabBarController = [[UITabBarController alloc] init]; 
self.window.rootViewController = self.tabBarController; 

有了這個:

#define IS_IPHONEX (([[UIScreen mainScreen] bounds].size.height-812)?NO:YES) 
self.tabBarController = [[UITabBarController alloc] init];  
self.window.rootViewController = [[UIViewController alloc] init] ; 
if(IS_IPHONEX) 
    self.window.rootViewController.view.frame = CGRectMake(self.window.rootViewController.view.frame.origin.x, self.window.rootViewController.view.frame.origin.y, self.window.rootViewController.view.frame.size.width, self.window.rootViewController.view.frame.size.height + 32) ; 
[self.window.rootViewController.view addSubview:self.tabBarController.view]; 
self.tabBarController.tabBar.barTintColor = [UIColor colorWithWhite:0.98 alpha:1.0] ; 
self.window.rootViewController.view.backgroundColor = [UIColor colorWithWhite:0.98 alpha:1.0] ; 

注意:這可能是一個錯誤,作爲視圖大小和標籤欄佈局由OS設置。它應該按照iPhone X人機界面指南中的Apple屏幕截圖顯示:https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/

+1

不固定我看到,我沒有編程創建Tab欄,我用故事板構建它的約束被設置爲屏幕的底部。對我來說,我們感到很奇怪,我們必須檢測它是否是iPhone X,然後對佈局進行一些調整,而它們只是通過它自身將TabBar的高度向上調整,而無需更改任何代碼。 –

+0

這種感覺對我來說更像是一個bug,我想我會對此做一個錯誤報告,看看它出了什麼問題。謝謝你的幫助!! –

+0

使用主屏幕邊界的確切高度來確定應用程序是否在iPhone X上運行真的不是一個好主意。如果明年的模型是相同的點大小,會發生什麼情況?或者,如果應用程序在橫向模式下運行? – roperklacks

-1

我遇到了同樣的問題,這是通過在標籤欄佈局後設置tabBar項來解決的。

在我的情況下,問題發生時:

  1. 有一個自定義視圖控制器
  2. 中的UITabBar一樣在視圖控制器的初始化創建
  3. 鑑於之前做過的標籤欄項目設置加載
  4. 在視圖中加載的標籤欄被添加到視圖控制器的主視圖中
  5. 然後,按照您提到的方式呈現項目。
1

我在嘗試在自定義TabBarController中設置UITabBar的框架時遇到了同樣的問題。

self.tabBar.frame = CGRectMake(0, self.view.frame.size.height - kTabBarHeight, self.view.frame.size.width, kTabBarHeight); 

當我只是把它調整到新的大小問題就走了

if(IS_IPHONE_X){ 
    self.tabBar.frame = CGRectMake(0, self.view.frame.size.height - kPhoneXTabBarHeight, self.view.frame.size.width, kPhoneXTabBarHeight); 
} 
else{ 
    self.tabBar.frame = CGRectMake(0, self.view.frame.size.height - kTabBarHeight, self.view.frame.size.width, kTabBarHeight); 
} 
+1

'kPhoneXTabBarHeight'的值是什麼? –

+0

我剛剛添加了32點到kTabBarHeight(這是45)的以前的值。但是您不必指定完全相同的值,對於我來說,它也可以正常工作,而無需指定tabBar的框架。但是,如果您確實指定了它,則必須調整iPhone X上的其他高度。 – Evgeny

+1

完全破解,但它是這些解決方案中唯一適合我的解決方案。 –

0

如果您對標籤欄嘗試刪除任何高度約束。

面對同樣的問題,並解決這個問題。

-1

我認爲這是來自iPhoneX的一個bug UIKit。 ,因爲它的工作原理:

if (@available(iOS 11.0, *)) { 
    if ([UIApplication sharedApplication].keyWindow.safeAreaInsets.top > 0.0) { 
     self.tabBarBottomLayoutConstraint.constant = 1.0; 
    } 
} 
+0

你可以給tabBarBottomLayoutConstraint是什麼更多信息? – user3099837

+0

是的,tabBarBottomLayoutConstraint是什麼? –

21

我能夠通過簡單地在UITabBar中viewDidLayoutSubviews呼籲invalidateIntrinsicContentSize來解決這個問題。

-(void)viewDidLayoutSubviews 
{ 
    [super viewDidLayoutSubviews]; 
    [self.tabBar invalidateIntrinsicContentSize]; 
} 

注:標籤欄的底部將需要包含到主視圖的底部,而不是安全區,並在標籤欄應該沒有高度約束。

+0

爲我工作。謝謝你:) – kemdo

+0

我有一個沒有高度限制的標籤欄,限於底部佈局指南,這對我沒有用。任何其他想法? –

+0

thx!適合我! –

1

我今天遇到了這個問題,用一個UITabBar手動添加到故事板中的視圖控制器,當用常數0對齊安全區域的底部時,我會得到問題,但將其更改爲1會解決問題。使UITabBar比正常情況下高出1個像素是我的應用程序可以接受的。

+0

沒有爲我工作。我正在使用手動添加的UITabBar。 –

+0

不理想,但似乎爲我工作 – Vad

3

固定用的子類UITabBar申請safeAreaInsets:

class SafeAreaFixTabBar: UITabBar { 

    var oldSafeAreaInsets = UIEdgeInsets.zero 

    @available(iOS 11.0, *) 
    override func safeAreaInsetsDidChange() { 
     super.safeAreaInsetsDidChange() 

     if oldSafeAreaInsets != safeAreaInsets { 
      oldSafeAreaInsets = safeAreaInsets 

      invalidateIntrinsicContentSize() 
      superview?.setNeedsLayout() 
      superview?.layoutSubviews() 
     } 
    } 

    override func sizeThatFits(_ size: CGSize) -> CGSize { 
     var size = super.sizeThatFits(size) 
     if #available(iOS 11.0, *) { 
      let bottomInset = safeAreaInsets.bottom 
      if bottomInset > 0 && size.height < 50 { 
       size.height += bottomInset 
      } 
     } 
     return size 
    } 
} 
+0

解決部分問題,但不是全部。請參閱下面的完整答案 –

-1

我在啓動屏幕故事板上遇到了這個bug,無法通過子類自定義。經過一些分析,我設法找出原因 - 我直接使用UITabBar。切換到封裝了UITabBarUITabBarController解決了該問題。

注 - 這可能會由iOS 11.1修復,因此可能不會影響真正的iPhone X應用程序(因爲iPhone X很可能會在iOS 11.1上發佈)。

-1

我在故事板中創建了新的UITabBarController,並將所有視圖控制器推送到了這個新的UITabBarConttoller。所以,在iPhone X模擬器中一切運行良好。

+0

這也爲我解決了它。 Xcode 9 IB生成解決問題的UITabBarController的XML的方式有些不同。 – Tiago

14

由VoidLess提供的答案只修復了TabBar問題的一部分。它修復了tabbar中的佈局問題,但是如果你使用viewcontroller來隱藏tabbar,在動畫過程中tabbar被錯誤地渲染(重現它最好是2有2個segues - 一個模式和一個push。如果你改變了segues,你可以看到不合適的標籤欄)。下面的代碼解決了這兩個問題。幹得好蘋果。

class SafeAreaFixTabBar: UITabBar { 

var oldSafeAreaInsets = UIEdgeInsets.zero 

@available(iOS 11.0, *) 
override func safeAreaInsetsDidChange() { 
    super.safeAreaInsetsDidChange() 

    if oldSafeAreaInsets != safeAreaInsets { 
     oldSafeAreaInsets = safeAreaInsets 

     invalidateIntrinsicContentSize() 
     superview?.setNeedsLayout() 
     superview?.layoutSubviews() 
    } 
} 

override func sizeThatFits(_ size: CGSize) -> CGSize { 
    var size = super.sizeThatFits(size) 
    if #available(iOS 11.0, *) { 
     let bottomInset = safeAreaInsets.bottom 
     if bottomInset > 0 && size.height < 50 && (size.height + bottomInset < 90) { 
      size.height += bottomInset 
     } 
    } 
    return size 
} 

override var frame: CGRect { 
    get { 
     return super.frame 
    } 
    set { 
     var tmp = newValue 
     if let superview = superview, tmp.maxY != 
     superview.frame.height { 
      tmp.origin.y = superview.frame.height - tmp.height 
     } 

     super.frame = tmp 
     } 
    } 
} 

Objective-C代碼:

@implementation VSTabBarFix { 
    UIEdgeInsets oldSafeAreaInsets; 
} 


- (void)awakeFromNib { 
    [super awakeFromNib]; 

    oldSafeAreaInsets = UIEdgeInsetsZero; 
} 


- (void)safeAreaInsetsDidChange { 
    [super safeAreaInsetsDidChange]; 

    if (!UIEdgeInsetsEqualToEdgeInsets(oldSafeAreaInsets, self.safeAreaInsets)) { 
     [self invalidateIntrinsicContentSize]; 

     if (self.superview) { 
      [self.superview setNeedsLayout]; 
      [self.superview layoutSubviews]; 
     } 
    } 
} 

- (CGSize)sizeThatFits:(CGSize)size { 
    size = [super sizeThatFits:size]; 

    if (@available(iOS 11.0, *)) { 
     float bottomInset = self.safeAreaInsets.bottom; 
     if (bottomInset > 0 && size.height < 50 && (size.height + bottomInset < 90)) { 
      size.height += bottomInset; 
     } 
    } 

    return size; 
} 


- (void)setFrame:(CGRect)frame { 
    if (self.superview) { 
     if (frame.origin.y + frame.size.height != self.superview.frame.size.height) { 
      frame.origin.y = self.superview.frame.size.height - frame.size.height; 
     } 
    } 
    [super setFrame:frame]; 
} 


@end 
+0

很好,謝謝! – YoCoh

+0

作品!謝謝! – runia

+0

爲我工作。謝謝你 – Mehrdad

1

我已經劃傷我的頭了這個問題。它似乎與tabBar如何初始化並添加到視圖層次結構有關。我也嘗試了上面的解決方案,如調用invalidateIntrinsicContentSize,設置框架,以及在UITabBar子類中的bottomInsets。他們似乎暫時工作,他們打破了一些其他情況或通過引起一些模糊的佈局問題來回歸標籤欄。當我調試這個問題時,我嘗試將高度約束分配給UITabBar和centerYAnchor,但是沒有解決問題。我在視圖調試器中意識到tabBar高度在問題複製之前和之後是正確的,這導致我認爲問題出現在子視圖中。我使用下面的代碼來成功解決這個問題,而不會退步任何其他場景。

- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 
{ 
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; 
    if (DEVICE_IS_IPHONEX()) 
    { 
     [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { 
      for (UIView *view in self.tabBar.subviews) 
      { 
       if ([NSStringFromClass(view.class) containsString:@"UITabBarButton"]) 
       { 
        if (@available (iOS 11, *)) 
        { 
         [view.bottomAnchor constraintEqualToAnchor:view.superview.safeAreaLayoutGuide.bottomAnchor].active = YES; 
        } 
       } 
      } 
     } completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { 
      [self.tabBar layoutSubviews]; 
     }]; 
    } 
} 

假設:我只爲iPhone X這樣做,因爲它似乎並沒有重現,此刻任何其他設備上。 基於Apple未在未來的iOS版本中更改UITabBarButton類的名稱這一假設。 我們只在UITabBarButton上這樣做時,意味着如果蘋果在UITabBar中添加更多內部子視圖,我們可能需要修改代碼以進行調整。

請lemme知道這是否有效,將開放的建議和改進!

爲此創建一個快速的等價物應該很簡單。

+0

我把它放在''viewDidAppear(animated:)''我的'UITabBarController'中,它工作正常。謝謝! –

+0

什麼參數你通過大小和協調員?從視圖didAppear – sulabh

7

有一個我們可以解決問題的技巧。

只要把你的UITabBar放入一個UIView。

這真的對我很有用。

或者您可以關注此Link瞭解更多詳情。

+3

這工作得很好,有一個uiview只是包含UITabBar。將約束放在UIView(L,R和Bottom)上的安全區域,給它一個高度(49),並將UITabBar約束在UIView的四周。 – sdsykes

+0

此解決方案適用於我。我沒有使用UITabController,只是UITabBar。 –

+0

爲我工作。謝謝 –

6

移動標籤欄距離底部 1分爲我工作。

當然,你會得到一個缺口,你必須以某種方式填寫,但文本/圖標現在正確定位。

1

從本教程:

https://github.com/eggswift/ESTabBarController

和標籤欄在AppDelegate類

(self.tabBarController.tabBar as? ESTabBar)?.itemCustomPositioning = .fillIncludeSeparator 

解決了我的標籤欄的問題寫這行的初始化後。

希望其解決您的問題

感謝

0

我有同樣的問題。

enter image description here

如果我設置任何非零常數的UITabBar的底部約束到安全區域:

enter image description here

它開始工作預期......

enter image description here

這是我做出的唯一改變,我不知道它爲什麼起作用但如果有人願意,我很想知道。

+1

這就是我最後得到它的工作,但是我不知道爲什麼或明白它在做什麼。對我來說,它仍然像一個錯誤 –

0

對於iPhone,你可以做到這一點,子類UITabBarController。

class MyTabBarController: UITabBarController { 

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 
    if #available(iOS 11, *) { 
     self.tabBar.heightAnchor.constraint(equalToConstant: 40).isActive = true 
     self.tabBar.invalidateIntrinsicContentSize() 
    } 
    } 
} 

轉到故事板,並允許使用安全區域佈局指南和變化類的的UITabBarControllerMyTabBarController

P.S該解決方案是不是在普及應用和iPad的情況下進行測試。

1

選擇的TabBar,並設置 「保存區域相對邊界」 複選框,在督察編輯是這樣的:

enter image description here

0

嘗試改變閃屏與@ 3X尺寸(3726×6624)

+0

如果我們使用LaunchScreen Storyboard? –

+0

沒關係,只是使用飛濺的新尺寸 – Sob7y

0

對於我刪除[self.tabBar setBackgroundImage:]工作,也許這是錯誤的UIKit

0

對我來說,這個固定的所有問題:

override func viewDidLayoutSubviews() { 
     super.viewDidLayoutSubviews() 
     let currentHeight = tabBar.frame.height 
     tabBar.frame = CGRect(x: 0, y: view.frame.size.height - currentHeight, width: view.frame.size.width, height: currentHeight) 
    } 
1

我的情況是,我已經設置在我的UITabBarController自定義UITabBar高度,就像這樣:

override func viewWillLayoutSubviews() {    
     var tabFrame = tabBar.frame 
     tabFrame.size.height = 60 
     tabFrame.origin.y = self.view.frame.size.height - 60 
     tabBar.frame = tabFrame 
    } 

刪除此代碼是爲的TabBar在iPhone上X.正確顯示