Создавайте красивые пользовательские интерфейсы для вашего UITabBar на iOS — часть 2

Привет незнакомец! Прошла минута!

Здорово, что вы здесь, во второй части моего руководства по UITabBar! Вы искали первую часть? Вы можете найти это здесь"!

Во второй части моего урока мы узнаем, как сделать эту центральную кнопку и как заставить ее вращаться. Я надеюсь, что вы очень мотивированы, потому что вам нужно будет наверстать упущенное здесь по математике. А математику никто не любит. Но нам нравится дизайн пользовательского интерфейса, поэтому иногда приходится оставлять место для расчетов. Вздох.

Шаг 4: Добавьте среднюю кнопку

Следующим шагом будет создание средней кнопки нашей панели вкладок. Я сделаю это, добавив следующий код перед функцией viewDidLoad():

var layerHeight = CGFloat()
var middleButton: UIButton = {
   let b = UIButton()
   let c = UIImage.SymbolConfiguration(pointSize: 15, weight: .heavy, scale: .large)
   b.setImage(UIImage(systemName: "plus", withConfiguration: c), for: .normal)
   b.imageView?.tintColor = .white
   b.backgroundColor = UIColor(named: “iDoxViewColor”)
   return b
}()

Далее нам нужно будет выполнить базовое форматирование. Я сделаю это, создав одну функцию, которую вы можете найти ниже, но сначала я объясню все, что она делает.

Он будет выполнять следующие действия:

  • отключите второй элемент панели вкладок, чтобы пользователь случайно не нажал кнопку, ведущую к пустому контроллеру представления:
DispatchQueue.main.async {
   if let items = self.tabBar.items {
      items[1].isEnabled = false 
   }
}
  • добавьте наш middleButton в вид панели вкладок и придайте ему форму, тень и, самое главное, положение:
// add middle button
tabBar.addSubview(middleButton)
let size = CGFloat(50)
let constant: CGFloat = -20 + ( layerHeight / 2 ) - 5
// set constraints
let constraints = [
   middleButton.centerXAnchor.constraint(equalTo: tabBar.centerXAnchor),
   middleButton.centerYAnchor.constraint(equalTo: tabBar.topAnchor, constant: constant),
   middleButton.heightAnchor.constraint(equalToConstant: size),
   middleButton.widthAnchor.constraint(equalToConstant: size)
]
for constraint in constraints {
   constraint.isActive = true
}
middleButton.layer.cornerRadius = size / 2
// shadow
middleButton.layer.shadowColor = tColor?.cgColor
middleButton.layer.shadowOffset = CGSize(width: 0, height: 8)
middleButton.layer.shadowOpacity = 0.75
middleButton.layer.shadowRadius = 13
// other
middleButton.layer.masksToBounds = false
middleButton.translatesAutoresizingMaskIntoConstraints = false
  • пользовательское действие при каждом нажатии кнопки:
// action
middleButton.addTarget(self, action: #selector(buttonHandler(sender:)), for: .touchUpInside)

В этот момент система должна выдать ошибку, потому что функция Objective-C buttonHandler(sender:) еще не создана. Мы сделаем это в ближайшее время, и ошибка должна исчезнуть сама по себе.

Вся функция должна выглядеть так:

Я буду вызывать функцию addMiddleButton() в самом конце нашей функции setUpTabBar(). Это делается для того, чтобы убедиться, что CAShapeLayer() уже находится внутри представления и настроено, так как я использую его значения y и height для создания нашей средней кнопки.

Запустите приложение и убедитесь, что положение кнопки соответствует ожидаемому.

Пришло время определить действие, связанное с этой кнопкой, и избавиться от этой надоедливой ошибки! Создайте функцию Objective-C buttonHandler(sender:), скопировав следующую строку в свой код:

@objc func buttonHandler(sender: UIButton) {
}

Внутри этой функции мы определим, какие действия будут выполняться этой кнопкой. Откроется ли новый контроллер представления? Не подожжет ли это ваш iPhone? Вызовет пришельцев и начнет межгалактические войны? Призовет ли он драконов Дейенерис, чтобы обрушить на нас свой гнев? Это зависит от вас. Я сама не осторожная девушка, поэтому мой просто повернется и покажет еще три кнопки. Лучше, чем три разгневанных дракона…

Шаг 5: Поверните кнопку

Это когда те из вас, кто был ужасен в математике и геометрии, будут разоблачены. Я знаю, это не для всех. Но это весело и просто, пока это хорошо объяснено! Итак, позвольте мне попытаться сделать это простым, чтобы это не было скучным или совершенно запутанным. Если вы уже знаете, о чем я говорю, или не хотите слишком углубляться в детали, вы можете просто перейти к части кода.

скучная часть…

Мы будем использовать метод CGAffineTransform(rotationAngle:) для поворота нашей кнопки. Угол не рассчитывается в градусах: поэтому это не так просто, как просто использовать 45 градусов, 90 градусов или 180 градусов. Нам нужно будет вычислить наш угол в радианах, что означает, что мы будем использовать радиус круга, чтобы определить, где наша фигура должна перестать вращаться.

Как многие из вас знают, длина окружности, деленная на ее диаметр, всегда дает число около 3,14, называемое пи, которое в математике обозначается следующим символом: π (греческая буква «Р»). Это означает, что если у нас есть круг диаметром 2 см, его длина окружности будет около 6,28 см.

По логике, если вы разделите половину окружности круга или половину окружности на его радиус, который равен половине диаметра, результат также будет 3,14: в приведенном выше примере круг диаметром 2 см будет иметь радиус 1 см и поэтому окружность 3,14 см.

Поскольку мы вычисляем наш угол, используя радиус круга, мы будем использовать полукруг в качестве эталона. Поскольку полукруг соответствует в градусах 180, а также 3,14, мы можем считать верными следующие утверждения:

  • в углах π соответствует 180 градусам по часовой стрелке;
  • -π соответствует 180 градусам против часовой стрелки.

Как вы можете видеть из моей презентации, я перемещаю свою кнопку на 45 градусов, чтобы превратить символ плюса, который предлагает что-то добавить, в символ креста, который предлагает что-то закрыть:

Вы нашли правильную формулу? Или вы сдаетесь во власть математики? Хорошо, в любом случае, вот решение:

π / 4 = 45 degrees

В Swift это будет выглядеть так:

CGFloat.pi / 4

…и самое интересное!

Во-первых, установите логическое значение buttonTapped и установите для него значение false:

var buttonTapped = false

И давайте заполним эту функцию x! Это будет работать следующим образом:

  • когда для логического значения x установлено значение false, кнопка сдвинется на 45 градусов, а когда для логического значения установлено значение true, она вернется в исходное положение;
  • фон кнопки изменится на белый, если он выбран, и снова станет фиолетовым, если не выбран;
  • кнопка будет иметь фиолетовую рамку при выборе и не будет рамки при выборе;
  • изображение кнопки изменится с белого на фиолетовое, если оно выбрано, и обратно на белое, если не выбрано;
  • кнопка будет иметь тень независимо от ее состояния.

Наша функция будет выглядеть так:

Если вы хотите, вы можете поиграть с продолжительностью анимации, цветами и углом поворота, чтобы увидеть, какая анимация вам больше нравится.

Запустите проект и убедитесь, что кнопка работает нормально:

Ух ты! Вы должны гордиться собой за то, что сделали это здесь!

Уже ждете третью часть? Проверьте это здесь:



Вам понравилось это руководство? Хорошо ли это сработало с вашим проектом?

Want to Connect?
Follow me on…
❤️ YouTube
💖 Dribbble
💜 Instagram
💙 Ko-Fi
🖤 GitHub