#swift #size #uibarbuttonitem
Вопрос:
Ниже приведен короткий фрагмент демо-кода, взятый из моего проекта. Он состоит из UINavigationBar, UINavigationItem и нескольких UIBarButtonItems. Нажатие на кнопку-кнопку выделяет ее и затемняет остальные. При этом понятно, что размер шрифта меняется, но я хочу, чтобы размер самих элементов barButtonItems был исправлен. Таким образом, когда я случайным образом нажимаю на элементы barButtonItems, они не кажутся покачивающимися, когда их текст заголовка сжимается и расширяется. Как заставить элементы barButtonItems сопротивляться изменению размера при изменении текста заголовка?
import UIKit
class ViewController: UIViewController {
var barButtonItems: [UIBarButtonItem]!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .darkGray
let navBar: UINavigationBar = UINavigationBar(frame: CGRect(x: 0, y: 100, width: view.frame.width, height: 40))
navBar.barTintColor = #colorLiteral(red: 0.1019607857, green: 0.2784313858, blue: 0.400000006, alpha: 1)
view.addSubview(navBar)
let navItem = UINavigationItem()
let appleBarBtnItem = UIBarButtonItem(title: "Apple", style: .plain, target: self, action: #selector(barItemTapped))
let bananaBarBtnItem = UIBarButtonItem(title: "Banana", style: .plain, target: self, action: #selector(barItemTapped))
let kiwiBarBtnItem = UIBarButtonItem(title: "Kiwi", style: .plain, target: self, action: #selector(barItemTapped))
let pearBarBtnItem = UIBarButtonItem(title: "Pear", style: .plain, target: self, action: #selector(barItemTapped))
let orangeBarBtnItem = UIBarButtonItem(title: "Orange", style: .plain, target: self, action: #selector(barItemTapped))
barButtonItems = [appleBarBtnItem, bananaBarBtnItem, kiwiBarBtnItem, pearBarBtnItem, orangeBarBtnItem]
navItem.leftBarButtonItems = barButtonItems
navBar.setItems([navItem], animated: false)
setCurrentBarItem(appleBarBtnItem)
}
func setCurrentBarItem(_ barBtnItem: UIBarButtonItem) {
for btn in barButtonItems {
highlight(btn, turnedOn: (btn == barBtnItem) )
}
}
func highlight(_ button: UIBarButtonItem, turnedOn: Bool) {
button.tintColor = #colorLiteral(red: 0.7230747342, green: 0.9554787278, blue: 0.9893732667, alpha: 1)
let weight: UIFont.Weight = turnedOn ? .bold : .thin
let attributes: [NSAttributedString.Key : Any] = [ .font: UIFont.systemFont(ofSize: 20, weight: weight)]
button.setTitleTextAttributes(attributes, for: .normal)
}
@objc func barItemTapped(_ sender: UIBarButtonItem) {
setCurrentBarItem(sender)
}
}
Ответ №1:
Одна из причин, по которой они колеблются, заключается в том, что вы настраиваете setTitleTextAttributes
только .normal
состояние. Добавьте его .selected
также, чтобы он меньше покачивался, однако это не решит вашу проблему полностью. Вот так
button.setTitleTextAttributes(attributes, for: .selected)
Я бы предложил попробовать добавить некоторое поле в элемент держателя текста пользовательского интерфейса элементов UIBarButtonItems. Может быть, это исправит!
Комментарии:
1. Нет, это не помогло. Похоже, мне придется отказаться от наличия
.bold
веса шрифта для выбранного элемента BarButtonItem и.thin
веса шрифта, когда это не так, потому что изменение веса шрифта увеличивает или уменьшает ширину элемента BarButtonItem. В конце концов я решил просто изменить цвета элементов barButtonItems и создать простую анимацию.
Ответ №2:
Похоже, мне придется отказаться от наличия .bold
веса шрифта для выбранного элемента BarButtonItem и .thin
веса шрифта, когда это не так, потому что изменение веса шрифта увеличивает или уменьшает ширину элемента BarButtonItem, заставляя сопоставляющие элементы BarButtonItem смещаться и покачиваться, когда я нажимаю на них. В конце концов я решил изменить только цвета элементов barButtonItems и предоставить простую анимацию:
func highlight(_ button: UIBarButtonItem, turnedOn: Bool) {
let tintColor = turnedOn ?
#colorLiteral(red: 0.7230747342, green: 0.9554787278, blue: 0.9893732667, alpha: 1)
:
#colorLiteral(red: 0.1901655495, green: 0.5488880277, blue: 0.7976593971, alpha: 1)
UIView.animate(withDuration: 0.2,
delay: 0,
options: [.allowUserInteraction, .curveEaseInOut],
animations: { button.tintColor = tintColor },
completion: nil)
}