UITabBarコンポーネントに関してiPhone Xシミュレータに問題がある人はいますか?
私のものはアイコンとタイトルを互いの上にレンダリングしているようです、私は何かが足りないかどうかわからない、私はそれをiPhone 8シミュレータでも走らせたストーリーボード。
iPhone X:
iPhone 8
ViewDidLayoutSubviewsのUITabBarでinvalidateIntrinsicContentSizeを呼び出すだけで、問題を回避できました。
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self.tabBar invalidateIntrinsicContentSize];
}
注:タブバーの下部は、安全な領域ではなくメインビューの下部に収まる必要があります。また、タブバーには高さの制限がありません。
VoidLessが提供する回答はTabBarの問題を部分的にしか解決しません。タブバー内のレイアウトの問題は解決されますが、タブバーを非表示にするviewcontrollerを使用すると、アニメーション中にタブバーが正しくレンダリングされません(再現するには2つのセグエがあります。タブバーが正しく配置されていないことを確認してください。以下のコードは両方の問題を解決します。良い仕事アップル。
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
問題を解決するためのトリックがあります。
あなたのUITabBarをUIViewの中に入れるだけです。
これは本当に私のために働いています。
または、もっと詳しく知りたい場合は、 リンク をたどってください。
safeAreaのUITabBar
sizeThatFits(_)
をオーバーライドする
extension UITabBar {
static let height: CGFloat = 49.0
override open func sizeThatFits(_ size: CGSize) -> CGSize {
guard let window = UIApplication.shared.keyWindow else {
return super.sizeThatFits(size)
}
var sizeThatFits = super.sizeThatFits(size)
if #available(iOS 11.0, *) {
sizeThatFits.height = UITabBar.height + window.safeAreaInsets.bottom
} else {
sizeThatFits.height = UITabBar.height
}
return sizeThatFits
}
}
これは私のカスタムviewWillAppear
のUITabBarController
に追加しました。
tabBar.invalidateIntrinsicContentSize()
tabBar.superview?.setNeedsLayout()
tabBar.superview?.layoutSubviews()
タブバーを下に移動する1ポイント下に移動するとうまくいきました。
もちろん、そうすることによってギャップを得るでしょう。それは何らかの方法で埋めなければなりませんが、テキスト/アイコンは適切に配置されます。
私はついにAppleを呪った何時間もの後にこれを考え出した。
UIKitは実際にこれを処理します、そしてシフトされたタブバー項目は不正確な設定(そしておそらく実際のUIKitバグ)が原因であるようです。サブクラス化やバックグラウンドビューは必要ありません。
Interface builderでも動作します。
愚かなのは、たとえあなたがIBが上記のステップで追加する正確な制約を追加したとしても、あなたはIBのバグを実際に見ることができるということです!
SafeAreaInsetsを適用するためにサブクラス化されたUITabBarを使用することで修正されました:
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
}
}
完了ブロックでモーダルを閉じた後に[tabController.view setNeedsLayout];
を呼び出すことによって私のために解決しました。
[vc dismissViewControllerAnimated:YES completion:^(){
UITabBarController* tabController = [UIApplication sharedApplication].delegate.window.rootViewController;
[tabController.view setNeedsLayout];
}];
私の場合は、次のように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で正しく表示されるようになりました。
UITabBarは、ホームボタン/線より上になるように高さが増加していますが、サブビューを元の場所に描画し、サブビューの上にUITabBarItemをオーバーレイしています。
回避策としては、iPhone Xを検出してからタブバーがホームラインの上の安全な領域に表示されるようにビューの高さを32ピクセル縮小します。
たとえば、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ヒューマンインターフェイスガイドラインのアップルのスクリーンショットに従って表示されるはずです: https://developer.Apple.com/ios/human-interface-guidelines/overview/iphone-x/
私は、ストーリーボードのView Controllerに手動で追加されたUITabBarを使用してこれに遭遇しました。セーフエリアの下部に0の定数で整列すると問題が発生しますが、1に変更すると問題が解決します。 UITabBarを通常より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);
}
私はこの問題について私の頭をかいた。 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でこれを行っているのは、AppleがUITabBarにさらに内部サブビューを追加する場合、それに合わせてコードを変更する必要がある可能性がある場合だけです。
これがうまくいくかどうかを教えてください、提案や改善の余地があります。
これと同等のSwiftを作成するのは簡単なはずです。
このチュートリアルから:
https://github.com/eggswift/ESTabBarController
タブバーの初期化後にappdelegateクラスでこの行を書いた
(self.tabBarController.tabBar as? ESTabBar)?.itemCustomPositioning = .fillIncludeSeparator
タブバーの問題を解決しました。
それがあなたの問題を解決することを願っています
ありがとう
私にとってはこれですべての問題が修正されました。
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)
}
私にとっては、[self.tabBar setBackgroundImage:]
workを削除してください。おそらくUIKitのバグです。
私が見つけた最も簡単な解決策は、タブバーの下部とsafeAreaLayoutGuide.bottomAnchorの下部の間に0.2ポイントのスペースを追加することです。
tabBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -0.2)
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()
}
}
}
ストーリーボードに移動してセーフエリアレイアウトガイドを使用し、UITabbarControllerのクラスを変更する MyTabBarControllerに
P.Sこのソリューションは、ユニバーサルアプリケーションおよびiPadの場合にはテストされていません。
Tab Barに高さの制限がある場合は、それを削除してみてください。
同じ問題に直面し、これを削除すると問題が解決しました。
私は同様の問題を抱えていました。最初は正しくレンダリングされていましたが、tabBarItemの1つにbadgeValue
を設定した後にレイアウトが壊れました。私が既に作成したUITabBar
サブクラスで、UITabBarController
をサブクラス化せずに動作したのはこれでした。
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
NSLayoutYAxisAnchor *tabBarBottomAnchor = self.tabBar.bottomAnchor;
NSLayoutYAxisAnchor *tabBarSuperviewBottomAnchor = self.tabBar.superview.bottomAnchor;
[tabBarBottomAnchor constraintEqualToAnchor:tabBarSuperviewBottomAnchor].active = YES;
[self.view layoutIfNeeded];
}
TabBarスーパービューを使用して、制約/アンカーが同じビュー階層にあることを確認し、クラッシュを回避します。
私の理解によると、これはUIKitのバグのように思われるので、自動レイアウトエンジンが再びタブバーを正しくレイアウトできるように、タブバーの制約を書き直すか再設定する必要があります。
ストーリーボードでUITabBarController
を使用していましたが、最初は問題なく動作していましたが、新しいXcodeバージョンにアップグレードすると、tabBarの高さに関連する問題が発生し始めました。
私にとっての修正は、既存のUITabBarController
をストーリーボードから削除し、それをインターフェイスビルダーオブジェクトライブラリからドラッグして再作成することでした。
ストーリーボードに新しいUITabBarControllerを作成し、すべてのView Controllerをこの新しいUITabBarConttollerにプッシュしました。だから、すべてのiPhone Xシミュレータでうまくいきます。
@ 3倍の大きさのスプラッシュスクリーンを変更しようとすると(3726×6624)