Настройте свой UITabBarController | Кодементор
С 2017 года тенденция дизайна изменилась на панель вкладок, а не на слайд-меню. UITabBarController
стал одним из самых популярных контроллеров. Его очень просто использовать. Но иногда это слишком просто настроить и сделать привлекательным. Дизайнеры — это художники, и обычно им нужна такая панель вкладок.
или вот так
Мне пришлось реализовать панель вкладок, как показано выше, в 2015 году. В то время моя реализация была плохой. я использовал UIViewController
в качестве основного контроллера и добавил настраиваемый вид, например панель вкладок. И каждый раз, когда выбрана вкладка, вставляйте другую UIViewController
в главный контроллер. Это не хороший вариант.
Сегодня я делаю UITabBarController
с пользовательским представлением, таким как панель вкладок. С этим решением мы можем использовать максимальную силу UITabBarController
с тем же поведением и кодом. Гораздо проще и лучше, чем моя реализация раньше. Надеюсь, что после этой заметки любой сможет легко настроить свой дизайн, если захочет.
knTabBarItem
Первое, что нужно настроить, это UITabBarItem
. UITabBarItem
недостаточно гибок, чтобы его можно было настроить на все, что я хочу. мне нужно использовать UIButton
.
class knTabBarItem: UIButton {
// (1)
var itemHeight: CGFloat = 0
// (2)
var lock = false
// (3)
var color: UIColor = UIColor.lightGray {
didSet {
guard lock == false else { return }
iconImageView.change(color: color)
textLabel.textColor = color
}}
// (4)
private let iconImageView = knUIMaker.makeImageView(contentMode: .scaleAspectFit)
private let textLabel = knUIMaker.makeLabel(font: UIFont.systemFont(ofSize: 11),
color: .black, alignment: .center)
convenience init(icon: UIImage, title: String,
font: UIFont = UIFont.systemFont(ofSize: 11)) {
self.init()
translatesAutoresizingMaskIntoConstraints = false
iconImageView.image = icon
textLabel.text = title
textLabel.font = UIFont(name: font.fontName, size: 11)
setupView()
}
// (5)
private func setupView() {
addSubviews(views: iconImageView, textLabel)
iconImageView.top(toView: self, space: 4)
iconImageView.centerX(toView: self)
iconImageView.square()
let iconBottomConstant: CGFloat = textLabel.text == "" ? -2 : -20
iconImageView.bottom(toView: self, space: iconBottomConstant)
textLabel.bottom(toView: self, space: -2)
textLabel.centerX(toView: self)
}
}
(1) (2) (3)
- Некоторые элементы вкладки могут быть больше других. Я могу легко установить высоту, чтобы они отличались от других.
- Некоторые элементы вкладки очень неприемлемы с другим цветом и не меняют цвет при выборе.
(4)
- knUIMaker — моя коллекция для создания элементов управления. Просто проще сделать UIButton, UIImageView, UILabel по коду.
(5)
addSubviews
,top
,centerX
,bottom
из моего knConstraints сделать автоматическую раскладку. Я поклонник автоматической компоновки программно, поэтому создавать элементы управления и устанавливать макеты с помощью кода — это то, что я делаю сотни раз каждый день.
Следующее, на чем я должен сосредоточиться, это UITabBar
.
class knTabBar: UITabBar {
// (1)
var kn_items = [knTabBarItem]()
convenience init(items: [knTabBarItem]) {
self.init()
kn_items = items
translatesAutoresizingMaskIntoConstraints = false
setupView()
}
override var tintColor: UIColor! {
didSet {
for item in kn_items {
item.color = tintColor
}}}
func setupView() {
backgroundColor = .white
if kn_items.count == 0 { return }
// (2)
let line = knUIMaker.makeLine(color: .gray, height: 0.5)
addSubviews(views: line)
line.horizontal(toView: self)
line.top(toView: self)
// (3)
var horizontalConstraints = "H:|"
let itemWidth: CGFloat = screenWidth / CGFloat(kn_items.count)
for i in 0 ..< kn_items.count {
let item = kn_items[i]
addSubviews(views: item)
if item.itemHeight == 0 {
item.vertical(toView: self)
}
else {
item.bottom(toView: self)
item.height(item.itemHeight)
}
item.width(itemWidth)
horizontalConstraints += String(format: "[v%d]", i)
if item.lock == false {
item.color = tintColor
}
}
horizontalConstraints += "|"
addConstraints(withFormat: horizontalConstraints, arrayOf: kn_items)
}
}
(1)
- я не могу переопределить
items
вUITabBar
поэтому я называю его немного похожим, чтобы легче было запомнить
(2)
- Добавьте линию, чтобы отделить панель вкладок от контроллера. Некоторым проектам нужен индикатор на выбранном элементе, я добавлю индикатор здесь.
(3)
- Гибкое добавление элементов программно. Спасибо Apple за автоматический макет программно.
knTabController
Самое простое здесь. Просто наследуй от UITabBarController
добавьте код, и все заработает.
class knTabController: UITabBarController {
var kn_tabBar: knTabBar!
var selectedColor = UIColor.darkGray
var normalColor = UIColor.lightGray {
didSet {
kn_tabBar.tintColor = normalColor
}}
private var kn_tabBarHeight: CGFloat = 49
override func viewDidLoad() {
super.viewDidLoad()
tabBar.isHidden = true
setupView()
}
func setupView() {}
private func setTabBar(items: [knTabBarItem], height: CGFloat = 49) {
guard items.count > 0 else { return }
kn_tabBar = knTabBar(items: items)
guard let bar = kn_tabBar else { return }
kn_tabBar.tintColor = normalColor
bar.kn_items.first?.color = selectedColor
view.addSubviews(views: bar)
bar.horizontal(toView: view)
bar.bottom(toView: view)
kn_tabBarHeight = height
bar.height(kn_tabBarHeight)
for i in 0 ..< items.count {
items[i].tag = i
items[i].addTarget(self, action: #selector(switchTab))
}
}
@objc func switchTab(button: UIButton) {
selectedIndex = button.tag
}
}
Это готово для новой панели вкладок. Просто используйте его в контроллере.
Как использовать?
- Наследовать класс
knTabController
к вашему контроллеру. - Переопределить
setupView
метод.
class DoctorController: knTabController {
override func setupView() {
let home = knTabBarItem(icon: #imageLiteral(resourceName: "home"), title: "Home")
let appointment = knTabBarItem(icon: #imageLiteral(resourceName: "appointment"), title: "Appointment")
let add = knTabBarItem(icon: #imageLiteral(resourceName: "add"), title: "")
add.lock = true
add.itemHeight = 66
let doctors = knTabBarItem(icon: #imageLiteral(resourceName: "doctors"), title: "Doctors")
let porfolio = knTabBarItem(icon: #imageLiteral(resourceName: "user"), title: "Porfolio")
let red = UIViewController()
red.view.backgroundColor = .red
let green = UIViewController()
green.view.backgroundColor = .green
let blue = UIViewController()
blue.view.backgroundColor = .white
let yellow = UIViewController()
yellow.view.backgroundColor = .yellow
let gray = UIViewController()
gray.view.backgroundColor = .gray
setTabBar(items: [home, appointment, add, doctors, porfolio])
viewControllers = [red, green, blue, yellow, gray]
normalColor = .red
}
}
- Беги и смотри. Основная кнопка (Hexagon Add) заблокирована, не меняйте цвет при выборе.
Будет намного лучше, если у нас будет анимация.
- В
knTabController
изменить методswitchTab
довольствоваться
let newIndex = button.tag
changeTab(from: selectedIndex, to: newIndex)
private func changeTab(from fromIndex: Int, to toIndex: Int) {
kn_tabBar.kn_items[fromIndex].color = normalColor
kn_tabBar.kn_items[toIndex].color = selectedColor
animateSliding(from: fromIndex, to: toIndex)
}
Надеюсь, это поможет любому, кто хочет настроить панель вкладок, сделать это без особых усилий. Код здесь.
Я добавлю еще несколько анимаций и некоторые свойства, чтобы сделать его более удобным в ближайшем будущем. Предложения и отзывы приветствуются.
Я поклонник Auto Layout Programmatically, поэтому обычно использую мою библиотеку, knConstraints для установки ограничений. knConstraints это очень простой способ настроить Auto Layout с очень легко читаемым синтаксисом. Вы можете попробовать сами здесь.