Пользовательский TabBarController с активным кругом - PullRequest
0 голосов
/ 14 января 2019

Прочитав несколько статей о пользовательских UITabBarControllers, я остался в замешательстве, чем прежде, чем вообще начал проводить исследования.

Моя цель - создать пользовательскую панель вкладок с 3 важными свойствами:

  • Нет текста, только значки
  • Активная иконка отмечена кружком, заполненным цветом позади него, и поэтому для нее нужен другой цвет пиктограммы

Вот что я пытаюсь достичь:

Example Tab Bar

Мне удалось удалить текст и отцентрировать значок, следуя другому ответу StackOverflow ( Удалить текст элемента панели вкладок, показать только изображение ), хотя решение мне кажется взломанным.

Как мне создать круг позади элемента и изменить цвет активного элемента?

Кроме того, не возражает ли кто-нибудь объяснить разницу между разделами инспектора XCode «Элемент панели вкладок» и «Элемент панели», которые отображаются непосредственно друг под другом?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Первый шаг прост: если оставить заголовок свойства UITabbarItem пустым, метка будет скрыта.

Ваш второй шаг можно разделить на два этапа: изменить цвет значка и добавить кружок за ним.

Первый шаг здесь снова прост: вы можете установить другой значок, чтобы использовать его для текущего выбранного ViewController (я использую раскадровки, этот процесс довольно прост). Что бы вы сделали, это добавили белую версию иконки, которая будет отображаться при выборе этого пункта меню.

Последний шаг - отображение круга. Для этого нам понадобится следующая информация:

  • Какой пункт сейчас выбран?
  • Какое положение значка на экране?

Первый из этих двух довольно легко обнаружить, но второй создает проблему: значки в UITabBar не распределены по экрану поровну, поэтому мы не можем просто разделить ширину панели вкладок на количество предметов в нем, а затем возьмите половину этого, чтобы найти центр значков. Вместо этого мы создадим подкласс UITabBarController.

Примечание: свойство tabBar UITabBarController имеет свойство .selectionIndicatorImage. Вы можете назначить изображение для этого, и оно будет показано позади вашего значка. Однако вы не можете легко контролировать размещение этого изображения, и поэтому мы все еще прибегаем к созданию подкласса UITabBarController.

class CircledTabBarController: UITabBarController {

    var circle: UIView?

    override func viewDidLoad() {
        super.viewDidLoad()
        let numberOfItems = CGFloat(tabBar.items!.count)
        let tabBarItemSize = CGSize(width: (tabBar.frame.width / numberOfItems) - 20, height: tabBar.frame.height)
        circle = UIView(frame: CGRect(x: 0, y: 0, width: tabBarItemSize.height, height: tabBarItemSize.height))
        circle?.backgroundColor = .darkGray
        circle?.layer.cornerRadius = circle!.frame.width/2
        circle?.alpha = 0
        tabBar.addSubview(circle!)
        tabBar.sendSubview(toBack: circle!)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let index = -(tabBar.items?.index(of: tabBar.selectedItem!)?.distance(to: 0))!
        let frame = frameForTabAtIndex(index: index)
        circle?.center.x = frame.origin.x + frame.width/2
        circle?.alpha = 1
    }

    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        let index = -(tabBar.items?.index(of: item)?.distance(to: 0))!
        let frame = frameForTabAtIndex(index: index)
        self.circle?.center.x = frame.origin.x + frame.width/2
    }

    func frameForTabAtIndex(index: Int) -> CGRect {
        var frames = tabBar.subviews.compactMap { (view:UIView) -> CGRect? in
            if let view = view as? UIControl {
                for item in view.subviews {
                    if let image = item as? UIImageView {
                        return image.superview!.convert(image.frame, to: tabBar)
                    }
                }
                return view.frame
            }
            return nil
        }
        frames.sort { $0.origin.x < $1.origin.x }
        if frames.count > index {
            return frames[index]
        }
        return frames.last ?? CGRect.zero
    }

}

Теперь используйте этот подкласс UITabBarController вместо базового класса.

Так почему этот подход вместо простого изменения значка на кружок? Потому что вы можете делать много разных вещей с этим. Я написал статью об анимации UITabBarController подобным образом , и, если хотите, вы можете легко использовать вышеприведенную реализацию, чтобы добавить анимацию к своей.

0 голосов
/ 14 января 2019

Самый простой и самый чистый способ сделать это - создать иконки и импортировать их в виде изображений в папку .xcassets. Затем вы можете просто установить разные значки для разных состояний для каждого из контроллеров view с помощью:

ViewController.tabBarItem = UITabBarItem(title: "", image: yourImage.withRenderingMode(.alwaysOriginal), selectedImage: yourImage)

выбранное вами изображение будет с кружком, а изображение без него. Это намного проще, чем манипулирование изображениями в xcode, и это также дешевле, поскольку компилятор должен только визуализировать изображения и не должен манипулировать ими.

О другом вопросе UIBarItem:

Абстрактный суперкласс для элементов, которые можно добавить в строку, отображаемую в нижней части экрана.

UITabBarItem является подклассом UIBarItem для обеспечения дополнительной функциональности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...