Ich weiß, dass diese Frage vor einiger Zeit beantwortet wurde, aber keiner der Lösungen erwähnte die direkte Verwendung einer UITabBar
und das Überschreiben ihrer UITabBarDelegate
tabBar(_, didSelect item:)
Methode, anstatt einen UITabBarController
die Auswahl indirekt handhaben zu lassen.
extension MyListViewController: UITabBarDelegate {
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
// Setze einen Filter basierend auf dem ausgewählten Element oder seinem Tag (Tag-Werte können in IB zugewiesen werden)
switch item.tag {
// Wende den Filter auf deine Datenquelle basierend auf dem item.tag an
}
// Oder wenn du einen CoreData NSFetchedResultsController verwendest, setze seine Prädikate:
// resultsController.predicate = makePredicate(item.tag)
// resultsController.performFetch()
tableView.reloadData()
}
}
Indem du UITabBarDelegate
Methoden direkt überschreibst, hast du direkte Kontrolle über das Auswahlverhalten des Tabs. So könntest du dieselbe Instanz deines UIViewController
wiederverwenden, anstatt dass der UITabBarController
ständig eine neue Instanz des UIViewController
für jeden Tab erstellt. Zum Beispiel könntest du in der didSelect
Methode einen Filter auf eine bestehende Liste von Elementen in einem UITableView
anwenden, anstatt eine neue Instanz der Liste in einem neuen UITableView
zu erstellen, wie es die anderen Lösungen tun.
Hinweis: Wenn du einen UITabBar
in deinem View Controller im Code oder in IB verwendest, erkennt UIKit dessen Existenz nicht und "unterlappende" Scrollansichten (z.B. UITableView
, UICollectionView
) passen ihre contentInset
nicht automatisch an. Auch wird das Verankern des unteren Teils des UITabBar
nicht korrekt auf einem Gerät mit nicht-nullen sicheren Bereichsrändern funktionieren, wenn du es an den unteren Bereich des sicheren Bereichs ankerst (es wird mit einer Lücke zwischen sich und dem Bildschirmrand "schweben").
Lösung (Teil 1): Setze die oberste Beschränkung speziell auf die UITabBar
-Instanz: Verankere zuerst den unteren Rand der Tab-Leiste am Superview
und den oberen Rand am unteren Rand des Sicheren Bereichs und setze die Konstante auf 49 (die Standardhöhe eines UITabBars zum Zeitpunkt dieses Schreibens). Dann wird es auf Geräten mit und ohne sicheren Bereich richtig aussehen.
Lösung (Teil 2): Du musst tableView.contentInset
/ collectionView.contentInset
manuell anpassen, um sicherzustellen, dass der Inhalt unter der Tab-Leiste gescrollt werden kann. Du musst sicherstellen, dass das unterste Element immer noch über die untere Tab-Leiste gescrollt werden kann:
-
Deaktiviere die automatische Anpassung des Inhaltsinsets in deinem viewDidLoad()
:
tableView.contentInsetAdjustmentBehavior = .never
-
Passe das UIScrollView.contentInset
an einer passenden Stelle an, füge die folgende Methode hinzu und rufe sie entweder in viewDidLoad()
auf oder wenn nötig jedes Mal, wenn die Ansicht in viewDidLayoutSubviews()
angeordnet wird. (Wenn viewDidLoad()
für dich zu früh ist, ist viewWillAppear()
wahrscheinlich auch zu früh.)
private func adjustScrollViewInsets() {
// Dieser Ausschnitt fügt nur den unteren Teil des Tabellenansichts-Inhalts hinzu, aber du musst beide obere und untere Ränder anpassen, wenn du auch einen oberen Navigationsbalken berücksichtigen musst.
var contentInset = tableView.contentInset
if let windowInsets = view.window ?? UIApplication.shared.keyWindow?.safeAreaInsets {
contentInset.bottom = windowInsets.bottom
} else {
contentInset.bottom = 0
}
tableView.contentInset = contentInset
}