使标签栏上的自定义按钮圆形
Posted
技术标签:
【中文标题】使标签栏上的自定义按钮圆形【英文标题】:Make custom button on Tab Bar rounded 【发布时间】:2016-03-15 14:26:00 【问题描述】:这是我想要做的:
注意:截图取自早期版本的 ios
我能够实现的目标:
代码:
override func viewWillAppear(animated: Bool)
// Creates image of the Button
let imageCameraButton: UIImage! = UIImage(named: "cameraIcon")
// Creates a Button
let cameraButton = UIButton(type: .Custom)
// Sets width and height to the Button
cameraButton.frame = CGRectMake(0.0, 0.0, imageCameraButton.size.width, imageCameraButton.size.height);
// Sets image to the Button
cameraButton.setBackgroundImage(imageCameraButton, forState: .Normal)
// Sets the center of the Button to the center of the TabBar
cameraButton.center = self.tabBar.center
// Sets an action to the Button
cameraButton.addTarget(self, action: "doSomething", forControlEvents: .TouchUpInside)
// Adds the Button to the view
self.view.addSubview(cameraButton)
我确实尝试以正常方式创建一个圆形按钮,但结果如下:
圆形按钮的代码片段:
//Creation of Ronded Button
cameraButton.layer.cornerRadius = cameraButton.frame.size.width/2
cameraButton.clipsToBounds = true
【问题讨论】:
这是通过在 TabBar 上添加一个按钮来完成的 这是不可能的,因为您无法将按钮添加到选项卡栏控制器视图。此外,添加到任一选项卡视图的任何按钮始终位于选项卡栏的后面。除此之外,如果我在单个视图中添加了一个按钮,则不会像上面描述的那样在所有视图中都可用。 不可能:D?我一开始是在告诉你这个想法,因为你在错误的控制器上添加了视图。为此,您需要继承UITabBarController
并在那里进行计算。您的答案已更新
是的,我误会了。谢谢@EridB
【参考方案1】:
解决方案
您需要继承UITabBarController
,然后在TabBar
的视图上方添加按钮。按钮操作应通过设置selectedIndex
触发UITabBarController
选项卡更改。
代码
下面的代码只是一种简单的方法,但是对于完全支持 iPhone(包括 X 系列)/iPad 版本,您可以在此处查看完整的存储库:EBRoundedTabBarController
class CustomTabBarController: UITabBarController
// MARK: - View lifecycle
override func viewDidLoad()
super.viewDidLoad()
let controller1 = UIViewController()
controller1.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 1)
let nav1 = UINavigationController(rootViewController: controller1)
let controller2 = UIViewController()
controller2.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 2)
let nav2 = UINavigationController(rootViewController: controller2)
let controller3 = UIViewController()
let nav3 = UINavigationController(rootViewController: controller3)
nav3.title = ""
let controller4 = UIViewController()
controller4.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 4)
let nav4 = UINavigationController(rootViewController: controller4)
let controller5 = UIViewController()
controller5.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 5)
let nav5 = UINavigationController(rootViewController: controller5)
viewControllers = [nav1, nav2, nav3, nav4, nav5]
setupMiddleButton()
// MARK: - Setups
func setupMiddleButton()
let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: 64, height: 64))
var menuButtonFrame = menuButton.frame
menuButtonFrame.origin.y = view.bounds.height - menuButtonFrame.height
menuButtonFrame.origin.x = view.bounds.width/2 - menuButtonFrame.size.width/2
menuButton.frame = menuButtonFrame
menuButton.backgroundColor = UIColor.red
menuButton.layer.cornerRadius = menuButtonFrame.height/2
view.addSubview(menuButton)
menuButton.setImage(UIImage(named: "example"), for: .normal)
menuButton.addTarget(self, action: #selector(menuButtonAction(sender:)), for: .touchUpInside)
view.layoutIfNeeded()
// MARK: - Actions
@objc private func menuButtonAction(sender: UIButton)
selectedIndex = 2
输出
【讨论】:
如果我们从 tabBarController 移动,如何隐藏这个按钮? 例如,如果我们移动或显示另一个屏幕。我是通过委托做的,但我认为它不正确。 @Alexsander 为此,您可以使用viewWillDisappear
隐藏按钮,并使用viewWillAppear
显示它。声明一个实例变量来保存按钮实例,以便在浏览应用程序时隐藏和显示它。
@Loebre 这段代码就是整个项目。没什么花哨的,把这个控制器设置为AppDelegate下的rootController就完成了
@Raymond26 @alizain-prasla 我写了一篇关于这个问题的博客以及如何使它与hidesBottomBarWhenPushed
一起工作:equaleyes.com/blog/2017/09/04/…【参考方案2】:
Swift 3 解决方案
对 EricB 的解决方案稍作调整以使其适用于 Swift 3,menuButton.addTarget() 方法需要对其选择器语法进行一些更改。
这里是新的 menuButton.addTarget() 函数:
menuButton.addTarget(self, action: #selector(MyTabBarController.menuButtonAction), for: UIControlEvents.touchUpInside)
在定义我的 TabBarController 类时,我还添加了一个 UITabBarControllerDelegate 并将所有的放在
override func viewDidAppear(_ animated: Bool) ...
为了更加清楚,完整的代码是:
全码解决方案
import UIKit
class MyTabBarController: UITabBarController, UITabBarControllerDelegate
// View Did Load
override func viewDidLoad()
super.viewDidLoad()
// Tab Bar Specific Code
override func viewDidAppear(_ animated: Bool)
let controller1 = UIViewController(self.view.backgroundColor = UIColor.white)
controller1.tabBarItem = UITabBarItem(tabBarSystemItem: UITabBarSystemItem.contacts, tag: 1)
let nav1 = UINavigationController(rootViewController: controller1)
let controller2 = UIViewController()
controller2.tabBarItem = UITabBarItem(tabBarSystemItem: UITabBarSystemItem.contacts, tag: 2)
let nav2 = UINavigationController(rootViewController: controller2)
let controller3 = UIViewController()
let nav3 = UINavigationController(rootViewController: controller3)
nav3.title = ""
let controller4 = UIViewController()
controller4.tabBarItem = UITabBarItem(tabBarSystemItem: UITabBarSystemItem.contacts, tag: 4)
let nav4 = UINavigationController(rootViewController: controller4)
let controller5 = UIViewController()
controller5.tabBarItem = UITabBarItem(tabBarSystemItem: UITabBarSystemItem.contacts, tag: 5)
let nav5 = UINavigationController(rootViewController: controller5)
self.viewControllers = [nav1, nav2, nav3, nav4, nav5]
self.setupMiddleButton()
// TabBarButton – Setup Middle Button
func setupMiddleButton()
let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: 64, height: 64))
var menuButtonFrame = menuButton.frame
menuButtonFrame.origin.y = self.view.bounds.height - menuButtonFrame.height
menuButtonFrame.origin.x = self.view.bounds.width / 2 - menuButtonFrame.size.width / 2
menuButton.frame = menuButtonFrame
menuButton.backgroundColor = UIColor.red
menuButton.layer.cornerRadius = menuButtonFrame.height/2
self.view.addSubview(menuButton)
menuButton.setImage(UIImage(named: "example"), for: UIControlState.normal)
menuButton.addTarget(self, action: #selector(MyTabBarController.menuButtonAction), for: UIControlEvents.touchUpInside)
self.view.layoutIfNeeded()
// Menu Button Touch Action
func menuButtonAction(sender: UIButton)
self.selectedIndex = 2
// console print to verify the button works
print("Middle Button was just pressed!")
【讨论】:
你好像忘记添加super.viewDidAppear(animated)了,谢谢解决:)【参考方案3】:这是 customTabbarcontroller 类,它是 UITabbarcontroller 的子类。这与@EridB 给出的想法相同。但是在他的代码中@Raymond26 的问题没有得到解决。因此,发布一个用 Swift 3.0
编写的完整解决方案protocol CustomTabBarControllerDelegate
func customTabBarControllerDelegate_CenterButtonTapped(tabBarController:CustomTabBarController, button:UIButton, buttonState:Bool);
class CustomTabBarController: UITabBarController, UITabBarControllerDelegate
var customTabBarControllerDelegate:CustomTabBarControllerDelegate?;
var centerButton:UIButton!;
private var centerButtonTappedOnce:Bool = false;
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews();
self.bringcenterButtonToFront();
override func viewDidLoad()
super.viewDidLoad()
self.delegate = self;
self.tabBar.barTintColor = UIColor.red;
let dashboardVC = DashboardViewController()
dashboardVC.tabBarItem = UITabBarItem(tabBarSystemItem: .topRated, tag: 1)
let nav1 = UINavigationController(rootViewController: dashboardVC)
let myFriendsVC = MyFriendsViewController()
myFriendsVC.tabBarItem = UITabBarItem(tabBarSystemItem: .featured, tag: 2)
let nav2 = UINavigationController(rootViewController: myFriendsVC)
let controller3 = UIViewController()
let nav3 = UINavigationController(rootViewController: controller3)
nav3.title = ""
let locatorsVC = LocatorsViewController()
locatorsVC.tabBarItem = UITabBarItem(tabBarSystemItem: .downloads, tag: 4)
let nav4 = UINavigationController(rootViewController: locatorsVC)
let getDirectionsVC = GetDirectionsViewController()
getDirectionsVC.tabBarItem = UITabBarItem(tabBarSystemItem: .history, tag: 5)
let nav5 = UINavigationController(rootViewController: getDirectionsVC)
viewControllers = [nav1, nav2, nav3, nav4, nav5]
self.setupMiddleButton()
// MARK: - TabbarDelegate Methods
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)
switch viewController
case is DashboardViewController:
self.showCenterButton()
case is MyFriendsViewController:
self.showCenterButton()
case is GetDirectionsViewController:
self.showCenterButton()
case is LocatorsViewController:
self.showCenterButton()
default:
self.showCenterButton()
// MARK: - Internal Methods
@objc private func centerButtonAction(sender: UIButton)
// selectedIndex = 2
if(!centerButtonTappedOnce)
centerButtonTappedOnce=true;
centerButton.setImage(UIImage(named: "ic_bullseye_white"), for: .normal)
else
centerButtonTappedOnce=false;
centerButton.setImage(UIImage(named: "ic_bullseye_red"), for: .normal)
customTabBarControllerDelegate?.customTabBarControllerDelegate_CenterButtonTapped(tabBarController: self,
button: centerButton,
buttonState: centerButtonTappedOnce);
func hideCenterButton()
centerButton.isHidden = true;
func showCenterButton()
centerButton.isHidden = false;
self.bringcenterButtonToFront();
// MARK: - Private methods
private func setupMiddleButton()
centerButton = UIButton(frame: CGRect(x: 0, y: 0, width: 64, height: 64))
var centerButtonFrame = centerButton.frame
centerButtonFrame.origin.y = view.bounds.height - centerButtonFrame.height
centerButtonFrame.origin.x = view.bounds.width/2 - centerButtonFrame.size.width/2
centerButton.frame = centerButtonFrame
centerButton.backgroundColor = UIColor.red
centerButton.layer.cornerRadius = centerButtonFrame.height/2
view.addSubview(centerButton)
centerButton.setImage(UIImage(named: "ic_bullseye_red"), for: .normal)
centerButton.setImage(UIImage(named: "ic_bullseye_white"), for: .highlighted)
centerButton.addTarget(self, action: #selector(centerButtonAction(sender:)), for: .touchUpInside)
view.layoutIfNeeded()
private func bringcenterButtonToFront()
print("bringcenterButtonToFront called...")
self.view.bringSubview(toFront: self.centerButton);
这是 DashboardViewController 供完整参考:
class DashboardViewController: BaseViewController, CustomTabBarControllerDelegate
override func viewDidLoad()
super.viewDidLoad()
(self.tabBarController as! CustomTabBarController).customTabBarControllerDelegate = self;
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated);
(self.tabBarController as! CustomTabBarController).showCenterButton();
override func viewWillDisappear(_ animated: Bool)
super.viewWillDisappear(animated);
self.hidesBottomBarWhenPushed = false;
(self.tabBarController as! CustomTabBarController).hideCenterButton();
override func viewWillLayoutSubviews()
super.viewWillLayoutSubviews();
if(!isUISetUpDone)
self.view.backgroundColor = UIColor.lightGray
self.title = "DASHBOARD"
self.prepareAndAddViews();
self.isUISetUpDone = true;
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
//MARK: CustomTabBarControllerDelegate Methods
func customTabBarControllerDelegate_CenterButtonTapped(tabBarController: CustomTabBarController, button: UIButton, buttonState: Bool)
print("isDrive ON : \(buttonState)");
//MARK: Internal Methods
func menuButtonTapped()
let myFriendsVC = MyFriendsViewController()
myFriendsVC.hidesBottomBarWhenPushed = true;
self.navigationController!.pushViewController(myFriendsVC, animated: true);
//MARK: Private Methods
private func prepareAndAddViews()
let menuButton = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
menuButton.titleLabel?.text = "Push"
menuButton.titleLabel?.textColor = UIColor.white
menuButton.backgroundColor = UIColor.red;
menuButton.addTarget(self, action: #selector(DashboardViewController.menuButtonTapped), for: .touchUpInside)
self.view.addSubview(menuButton);
【讨论】:
非常感谢它节省了我的时间。我有一个问题,当我点击自定义中心按钮时,我希望背景变得模糊并且控制应该在同一个控制器上(我不想要黑屏,查看 Asana 应用程序了解更多信息)。你能建议我如何达到同样的效果吗?【参考方案4】:使用情节提要: 单击要突出显示的特定标签栏项目的视图控制器中的标签栏按钮,
删除文本,只需将图像插入顶部设置为标签栏按钮的 -25。 检查如下图
【讨论】:
您好,图片不显示。请查看以下链接***.com/questions/18068597/… 行上方的视图不可点击。以上是关于使标签栏上的自定义按钮圆形的主要内容,如果未能解决你的问题,请参考以下文章