Ändern Sie die Höhe der UITabBar

70

Ich verwende UITabBarControllerals Root-Ansicht und App unterstützt iOS 6 und höher. Die Projektklassenhierarchie ist wie folgt.

UITabBarController
  - tab1
    - UINavigationController
      - UIViewController
      - UIViewController
      .
      .
  - tab2
    - UINavigationController
      - UIViewController
      - UIViewController
      .
      .
      .
  - tab3
    - UIViewController
  - tab4
    - UIViewController

Ich habe den folgenden Code verwendet, um die Höhe UITabBareines der UIViewController (der sich darin befindet UINavigationController) in der obigen Hierarchie zu ändern .

CGRect tabbarFrame = self.tabBarController.tabBar.frame;
tabbarFrame.size.height += 60;
self.tabBarController.tabBar.frame = tabbarFrame;

Aber es ändert nicht die Höhe. UITabBarwird mit der Standardhöhe angezeigt. Durch die Protokollierung wird der geänderte Wert wie unten gezeigt gedruckt.

<UITabBar: 0xb528f60; frame = (0 431; 320 109); autoresize = W+TM; layer = <CALayer: 0xb529080>>

Wie kann ich die UITabBarGröße ändern , um so etwas zu erreichen?

Geben Sie hier die Bildbeschreibung ein

Geek
quelle
Sie können die Standardhöhe der Registerkarten ändern, aber Sie müssen UITabBarController in eine Unterklasse unterteilen. Ich habe es bereits getan. Ich habe es auf stackoverflow.com/questions/16740824/tab-bar-with-large-icons/…
limon
Gefunden, dass dies funktionierte -> stackoverflow.com/a/27494228/1484378
keji
Ich denke, Sie können auch einfach eine Höhenbeschränkung festlegen, es schien mir zu funktionieren.
Giovannipds

Antworten:

141

Ich war mit diesem Problem konfrontiert und konnte es lösen.

Sie müssen Ihrer UITabBarControllerKlassenunterklasse folgenden Code hinzufügen .

const CGFloat kBarHeight = 80;

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    CGRect tabFrame = self.tabBar.frame; //self.TabBar is IBOutlet of your TabBar
    tabFrame.size.height = kBarHeight;
    tabFrame.origin.y = self.view.frame.size.height - kBarHeight;
    self.tabBar.frame = tabFrame;
}

Schnell:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    tabBar.frame.size.height = kBarHeight
    tabBar.frame.origin.y = view.frame.height - kBarHeight
}
Rushikesh
quelle
Können Sie etwas mehr angeben? Ich habe diesen Code zu meiner Klasse hinzugefügt, die TabBarController erweitert, und nichts ist passiert
voghDev
8
Ihre viewWillLayoutSubviewsImplementierung sollte super aufrufen, wahrscheinlich als erste Zeile.
Dklionsk
1
@Dklionsk Es könnte anrufen super, aber es muss nicht: The default implementation of this method does nothing.(aus den Dokumenten)
Dmirkitanov
1
@ Dmirkitanov das ist wahr für ein, UIViewControlleraber möglicherweise nicht wahr fürUITabBarController
Alex Pretzlav
15
Wechsel viewWillLayoutSubviewszu viewDidLayoutSubviewsiOS 13.
Arlomedia
43

Für iOS 8.2 , Xcode 6.2 Schnelle Sprache:

Erstellen Sie eine "DNMainTabVC.swift" -Datei (DeveloperNameMainTabViewController.swift) für Ihre UITabBarController(vom Typ UITabBarController) und verbinden Sie sie mit Ihrer Storyboard-VC.

Fügen Sie die folgenden Zeilen hinzu:

override func viewWillLayoutSubviews() {
    var tabFrame = self.tabBar.frame
    // - 40 is editable , the default value is 49 px, below lowers the tabbar and above increases the tab bar size
    tabFrame.size.height = 40
    tabFrame.origin.y = self.view.frame.size.height - 40
    self.tabBar.frame = tabFrame
}

Das hat bei mir funktioniert.

MB_iOSDeveloper
quelle
@MS_iOSDeveloper: Was meinst du mit "Verbinden mit Storyboard VC"? Wie verbinde ich es? Vielen Dank!
Rock
1
Du gehst zu deinem Storyboard. Klicken Sie auf den Viewcontroller und gehen Sie zur rechten Seite von Xcode zum "View Inspector". Unter der dritten Registerkarte (die wie eine Zeitung aussieht) finden Sie ein "Klassen" -Label. Der graue Platzhaltertext sollte "UIViewController" lauten. Dort geben Sie den Namen Ihrer Viewcontroller-Datei ein, z. "DNMainTabVC". Danach erscheint ein Pfeil im Feld neben "DNMainTabVC". Dies bedeutet, dass die Viewcontroller-Datei (.swift) mit dem Storyboard-Element verbunden ist. Was auch immer Sie in "DNMainTabVC.swift" schreiben, wirkt sich auf das Storyboard VC aus.
MB_iOSDeveloper
@MS_iOSDeveloper hat es verstanden. Es wird also eine benutzerdefinierte Klasse ausgewählt. Ich dachte, Sie meinten eine "Ziehen" -Aktion, um "eine Verbindung herzustellen". Ich habe es geschafft. danke fürs erklären!
Rock
38

Getestet in XCode 9.0 und Swift 4

Wie in den vorherigen Antworten vorgeschlagen - erben UITabBarund überschreiben sizeThatFits, aber heightals markieren @IBInspectable, damit es im Interface Builder festgelegt werden kann :

import UIKit

class CustomTabBar : UITabBar {
    @IBInspectable var height: CGFloat = 0.0

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        var sizeThatFits = super.sizeThatFits(size)
        if height > 0.0 {
            sizeThatFits.height = height
        }
        return sizeThatFits
    }
}

Set - CustomTabBarKlasse für den UITabBarin dem Identity - Inspector (⌥⌘3):

Identitätsinspektor der Registerkartenleiste

Stellen Sie dann im Attributinspektor (⌥⌘4) den gewünschten Wert Height(größer als ) ein:0.0

Inspektor für Registerkartenleistenattribute

msrdjan
quelle
Haben Sie darüber nachgedacht, eine Erweiterung anstelle der benutzerdefinierten Klasse zu erstellen? Und dann @IBInspectable var heightin der Erweiterung angeben. Wenn dies möglich ist, kann der zweite Schritt der Angabe der benutzerdefinierten Klasse vermieden werden.
Vipin Johney
1
Funktioniert nicht gut auf dem iPhone X. Sie müssen diese Lösung verwenden: stackoverflow.com/a/50346008/1702909
Jindřich Rohlík
37

Swift3.0, Swift 4.0 kompatibel

Standardhöhe der Registerkartenleiste vor dem iPhone X : 49pt

Standardhöhe der iPhone X- Registerkartenleiste: 83pt

Eine universelle Lösung, die jedes iOS-Gerät einschließlich der iPhone X- Bildschirmgröße unterstützt, würde folgendermaßen aussehen:

  1. Erfassen Sie die Standardhöhe von UITabBar:

    fileprivate lazy var defaultTabBarHeight = { tabBar.frame.size.height }()
    
  2. Passen Sie die Höhe der UITabBar an:

        override func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
    
            let newTabBarHeight = defaultTabBarHeight + 16.0
    
            var newFrame = tabBar.frame
            newFrame.size.height = newTabBarHeight
            newFrame.origin.y = view.frame.size.height - newTabBarHeight
    
            tabBar.frame = newFrame
        }
    
Kiarash Asar
quelle
1
Dies wird die TabBar springen lassen, wenn eine Ansichtsänderung animiert wird (wie das Ausblenden einer Statusleiste)
jakedunc
2
@jakedunc Ich denke, es ist das Problem, das S. Azzopardi sagte, ich habe diesen Code in viewDidLayoutSubviews () eingefügt und es funktioniert gut.
Ioio007
@ ioio007 Hallo, das funktioniert gut für iPhone x und andere Geräte. Aber wenn ich die Höhe erhöhe, versteckt sich UIView unten entsprechend dem Erhöhungswert. Hilf mir, die Lösung zu finden.
Saravanan
Hallo @Saravanan, sieht so aus, als ob Ihr Problem mit dem Kommentar unter dieser Antwort dasselbe ist
ioio007
Ändern Sie viewWillLayoutSubviews in viewDidLayoutSubviews in der UITabBarViewController-Klasse. Dies funktioniert einwandfrei. es ist für mich gearbeitet.
Sahil Omer
29

Erstellen Sie eine benutzerdefinierte Unterklasse vom Typ UITabBarund implementieren Sie die folgende Methode:

@implementation CustomTabBar
#define kTabBarHeight = // Input the height we want to set for Tabbar here
-(CGSize)sizeThatFits:(CGSize)size
{
    CGSize sizeThatFits = [super sizeThatFits:size];
    sizeThatFits.height = kTabBarHeight;

    return sizeThatFits;
}
@end

Hoffe das wird funktionieren.

sKhan
quelle
1
Großartig! Dies ist bisher die beste Lösung, die ich gesehen habe. Da es den Rahmen nicht direkt ändert, sondern stattdessen die erwartete Größe ändert! Großartig!
Vilanovi
Diese Antwort hat keine Nebenwirkungen hinsichtlich des automatischen Layouts der Controller für die innere Ansicht und sollte die akzeptierte Antwort sein.
Tsuz
Wie können wir dies verwenden, wenn wir die Registerkartensteuerung programmgesteuert erstellen?
EI Captain v2.0
14

Für Swift 4

extension UITabBar {

     override open func sizeThatFits(_ size: CGSize) -> CGSize {
     var sizeThatFits = super.sizeThatFits(size)
     sizeThatFits.height = 60 // adjust your size here
     return sizeThatFits
    }
 }
Merichle
quelle
11

Swift 2.0:

var tabBar:UITabBar?

override func viewWillLayoutSubviews() {
    var tabFrame: CGRect = self.tabBar!.frame
    tabFrame.size.height = 60
    tabFrame.origin.y = self.view.frame.size.height - 60
    self.tabBar!.frame = tabFrame
}
AG
quelle
Funktioniert nicht mehr in Swift 2.2. Es lässt einen freien Raum unter dem ursprünglichen Rahmen der Registerkartenleiste
jaytrixz
@ Jaytrixz hatte das gleiche Problem. Das Leerzeichen wird angezeigt, wenn Sie Alvins Code in viewDidLoad () einfügen, aber nicht, wenn Sie ihn wie vorgeschlagen in viewWillLayoutSubviews ()
einfügen
10

Swift 3.0+ Ersetzen Sie 200 im folgenden Code auf die gewünschte Höhe.

   extension UITabBar {
        override open func sizeThatFits(_ size: CGSize) -> CGSize {
            return CGSize(width: UIScreen.main.bounds.width, height: 200)
        }
    }
William Hu
quelle
Achtung! Das Verhalten ist undefiniert, welche Methodenimplementierung zur Laufzeit verwendet wird - Original aus der UITabbar-Klasse oder Ihrer Erweiterung
Alexander Larionov
Funktioniert wie Charme
Rockdaswift
Sie sollten KEINE Methoden überschreiben, die Swift-Erweiterungen (oder Objective-C-Kategorien) verwenden. Wenn Sie den sizeThatFits()Ansatz verwenden möchten, verwenden Sie stattdessen diese Lösung: stackoverflow.com/a/46425620/538491
Roberto
10

Swift 4 & kompatibel mit iPhone x

class CustomTabBar : UITabBar {

@IBInspectable var height: CGFloat = 65.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 height > 0.0 {

        if #available(iOS 11.0, *) {
            sizeThatFits.height = height + window.safeAreaInsets.bottom
        } else {
            sizeThatFits.height = height
        }
    }
    return sizeThatFits
}
}
seggy
quelle
Ich habe diese Methodendefinition in einem verwendet extension, da ich alle UI-Elemente programmgesteuert erstelle und beim Versuch, die tabBarvon my tabBarControllerdurch Überschreiben des tabBarAttributs festzulegen, eine leere tabBar (ohne Elemente)
angezeigt wird
guard let window = UIApplication.shared.keyWindow ist in iOS 13.0 veraltet. Also bitte aktualisieren.
Chandan Jee
7

Aufbauend auf früheren Antworten und Aktualisierung für Swift 3.

Unterklasse UITabController und stellen Sie sicher, dass Sie Ihre neue benutzerdefinierte Klasse dem Identitätsinspektor Ihres UITabControllers zuweisen.

Swift 3.0

class MainTabBarController: UITabBarController {

    override func viewWillLayoutSubviews() {
        var newTabBarFrame = tabBar.frame

        let newTabBarHeight: CGFloat = 60
        newTabBarFrame.size.height = newTabBarHeight
        newTabBarFrame.origin.y = self.view.frame.size.height - newTabBarHeight

        tabBar.frame = newTabBarFrame
    }
}

Warnung : Wenn unter Ihrer Registerkartenleiste ein Leerzeichen angezeigt wird, stellen Sie sicher, dass Sie diesen Code in viewWillLayoutSubviews () und nicht in viewDidLoad () eingefügt haben.

Kqtr
quelle
Dies funktioniert, jedoch wurde ein Teil der Ansicht aufgrund der erhöhten Höhe durch die Registerkartenleiste blockiert. Haben Sie eine Idee, wie Sie dies lösen können?
John
Hey @john. Befestigen Sie sie am unteren Rand des sicheren Bereichs?
Kqtr
Hallo @Kqtr, ich habe die Ansicht an die untere Ansicht geheftet wie: NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutAttribute.equal, toItem: view, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0) Ich habe gefunden safeAreaInsetsund safeAreaLayoutGuideaber die Funktion ist nur für iOS 11 und höher verfügbar. Beziehen Sie sich darauf?
John
Ja, Sie können unter iOS 11 und höher versuchen, view.safeAreaLayoutGuide.bottomAnchor zu verwenden, wobei view die Hauptansicht des VC ist. Und unter iOS 11 an VC's bottomLayoutGuide.topAnchor anheften. Derzeit verwenden Sie den unteren Bereich der Ansicht, und die Ansicht ist möglicherweise niedriger als die unteren Hilfslinien.
Kqtr
@john auch, FYI, der Einfachheit halber habe ich 4 Variablen in einer VC-Erweiterung erstellt, die einfache Einschränkungen für die Verwendung bietet (Wiederholung für links rechts und oben): Erweiterung UIViewController {var safeBottomAnchor: NSLayoutYAxisAnchor {if #available (iOS 11.0, *) {return view.safeAreaLayoutGuide.bottomAnchor} else {return bottomLayoutGuide.topAnchor}}}
Kqtr
7

Aus irgendeinem Grund funktionierte die Antwort von @Rushikesh bis iOS 10 ziemlich gut, aber ich hatte einige Probleme mit iOS 11 und Swift 3.2 .

Die Registerkartenleiste änderte ihren Rahmen jedes Mal, wenn ich eine neue Registerkarte berührte.

Ich habe dies behoben, indem ich den Code in die viewDidLayoutSubviews()Funktion anstatt eingefügt habeviewWillLayoutSubviews()

Swift 3:

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()
    var tabFrame            = tabBar.frame
    tabFrame.size.height    = 65
    tabFrame.origin.y       = view.frame.size.height - 65
    tabBar.frame            = tabFrame
}
S. Azzopardi
quelle
5

Xamarin-Implementierung:

public override void ViewWillLayoutSubviews()
{
    base.ViewWillLayoutSubviews();
    const float newTabBarHeight = 40f;
    TabBar.Frame = new CGRect(TabBar.Frame.X, TabBar.Frame.Y + (TabBar.Frame.Height - newTabBarHeight), TabBar.Frame.Width, newTabBarHeight);
}
Alexey Strakh
quelle
5

Die Antworten von Kiarash Asar wurden unter Verwendung des sicheren Bereichs bearbeitet:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    var safeAreaBottomInset: CGFloat = 0.0

    if #available(iOS 11.0, *) {
        safeAreaBottomInset = view.safeAreaInsets.bottom
    }

    let newTabBarHeight: CGFloat = {{myDesiredHeight}} + safeAreaBottomInset

    var newFrame = tabBar.frame
    newFrame.size.height = newTabBarHeight
    newFrame.origin.y = view.frame.size.height - newTabBarHeight

    tabBar.frame = newFrame
}
jonaszmclaren
quelle
4

Sie können die Höhe der Registerkartenleiste ändern, indem Sie sie in Unterklassen unterteilen. Das habe ich eigentlich schon vor langer Zeit gemacht. xcode 6.0

override func sizeThatFits(_ size: CGSize) -> CGSize {
    return CGSize(width: super.sizeThatFits(size).width, height: 60)
}

Das sollte seine Standardbreite mit der Höhe von 60 Punkten zurückgeben.

NFerocious
quelle
4

Dies ist auch eine Möglichkeit, dies zu tun

extension UITabBar {

override public func sizeThatFits(size: CGSize) -> CGSize {
    super.sizeThatFits(size)
    var sizeThatFits = super.sizeThatFits(size)
    sizeThatFits.height = 71 // or whatever height you need
    return sizeThatFits
   } 
}
Sultan Ali
quelle
3

ARBEITET MIT ALLEN BILDSCHIRMGRÖSSEN: Stellen Sie die tabBarHeight auf die (ursprüngliche Höhe der tabBar - 20) ein. Dies ist wichtig, damit Sie sie später in den viewDidLayoutSubviews verwenden können, auch besser als die gewünschte Größe hart zu codieren. Da diese Größe möglicherweise nicht auf allen Bildschirmen funktioniert.

Fenstersichere Bereichseinsätze halten die erforderliche Polsterung am unteren Rand der Registerkarte-Leiste aufrecht, um den Abstand vom unteren Rand des Bildschirms einzuhalten.

var tabBarHeight = CGFloat()

override func viewDidLoad() {
        super.viewDidLoad()
        tabBarHeight = self.tabBar.frame.height - 20
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        var tabFrame = self.tabBar.frame
        guard let window = UIApplication.shared.keyWindow else {return}
        tabFrame.size.height = tabBarHeight + window.safeAreaInsets.bottom
        self.tabBar.frame = tabFrame
    }
BrooklynCoder
quelle
1

iPhoneX haben unterschiedliche Höhen. Wenn wir also auf eine kleinere Höhe wechseln, ist die Form der Registerkarten in iPhoneX schlecht

- (void)viewWillLayoutSubviews
{
    int requiredHeight = 55;
    CGRect tabFrame = self.tabBar.frame;
    if (tabFrame.size.height < requiredHeight)
    {
        tabFrame.size.height = requiredHeight;
        tabFrame.origin.y = self.view.frame.size.height - requiredHeight;
        self.tabBar.frame = tabFrame;
    }
}
Abeer Iqbal
quelle
0

Swift 5.3.1, XCode 11+, iOS 14:

import UIKit

class CustomTabBar: UITabBar {
    let height: CGFloat = 62
    
    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        guard let window = UIApplication.shared.connectedScenes
                .filter({$0.activationState == .foregroundActive})
                .map({$0 as? UIWindowScene})
                .compactMap({$0})
                .first?.windows
                .filter({$0.isKeyWindow}).first else {
            return super.sizeThatFits(size)
        }

        var sizeThatFits = super.sizeThatFits(size)
        if #available(iOS 11.0, *) {
            sizeThatFits.height = height + window.safeAreaInsets.bottom
        } else {
            sizeThatFits.height = height
        }
        return sizeThatFits
    }
}
David Kyslenko
quelle
0

Klasse TabBarVC: UITabBarController {

//MARK:- Variable
let HEIGHT_TAB_BAR:CGFloat = 500

override func viewDidLoad() {
    super.viewDidLoad()
    
    // Do any additional setup after loading the view.
}


override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    var tabFrame = self.tabBar.frame
    tabFrame.size.height = HEIGHT_TAB_BAR
    tabFrame.origin.y = self.view.frame.size.height - HEIGHT_TAB_BAR
    self.tabBar.frame = tabFrame
}

}}

Hat gut für mich funktioniert.

Sahil Omer
quelle