我们如何创建一个更大的中心 UITabBar 项

Posted

技术标签:

【中文标题】我们如何创建一个更大的中心 UITabBar 项【英文标题】:How do we create a bigger center UITabBar Item 【发布时间】:2015-08-12 05:04:32 【问题描述】:

我想知道我们如何创建一个更大的中心 UITabBar,如下图所示?真的很漂亮!!!

【问题讨论】:

【参考方案1】:

仅使用 Xcode

单击要突出显示的特定标签栏项目的视图控制器中的标签栏按钮,

删除文本,只需将图像插入顶部设置为标签栏按钮的 -25。

喜欢下面的图片

之后

转到资产,选择您在标签栏按钮中设置的图像,设置属性渲染为原始图像(如果您有彩色按钮,否则它会渲染为一种颜色) 如下图,

现在,你会得到你想要的,

编辑:要使上半部分可点击,继承 UITabBar

class ProminentTabBar: UITabBar 
    var prominentButtonCallback: (()->())?
    
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? 
        guard let items = items, items.count>0 else 
            return super.hitTest(point, with: event)
        
        
        let middleItem = items[items.count/2]
        let middleExtra = middleItem.imageInsets.top
        let middleWidth = bounds.width/CGFloat(items.count)
        let middleRect = CGRect(x: (bounds.width-middleWidth)/2, y: middleExtra, width: middleWidth, height: abs(middleExtra))
        if middleRect.contains(point) 
            prominentButtonCallback?()
            return nil
        
        return super.hitTest(point, with: event)
    

然后在 TabBarController 中添加这个

override func viewDidLoad() 
    super.viewDidLoad()
    
    let prominentTabBar = self.tabBar as! ProminentTabBar
    prominentTabBar.prominentButtonCallback = prominentTabTaped


func prominentTabTaped() 
    selectedIndex = (tabBar.items?.count ?? 0)/2

请记住,UITabBar 没有很好的解决方案 :-)

【讨论】:

您还需要从底部算起 25 个边距,否则图像将显示为椭圆形。 工作正常,但是当我单击按钮时出现一个问题,整个按钮颜色变为蓝色。和图像不显示如何处理它? 你对那个按钮进行了子类化吗? 这在视觉上效果很好,但它只接受标签栏范围内的点击。有什么方法可以记录从圆圈顶部 1/3 开始的点击? 嗯.. 我可以让它在 iPhone 设备上居中,但是一旦在 iPad 上打开它就不行了。【参考方案2】:

我建议你看看下面的文章。 它解释了如何自定义一个提升主按钮的标签栏。

代码:

UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[button setBackgroundImage:highlightImage forState:UIControlStateHighlighted];

CGFloat heightDifference = buttonImage.size.height - self.tabBar.frame.size.height;
if (heightDifference < 0)
   button.center = self.tabBar.center;
else

 CGPoint center = self.tabBar.center;
 center.y = center.y - heightDifference/2.0;
 button.center = center;


[self.view addSubview:button];

指南: https://github.com/boctor/idev-recipes/tree/master/RaisedCenterTabBar

【讨论】:

该链接的域已过期。在您的代码中,“self”是 UITabBarController? @cohenadair self 将是 UIViewController。我添加了一个带有example 的 Github 存储库链接【参考方案3】:

斯威夫特 3、4:

我在UITabBarController 的子类的viewDidLoad 中使用此代码:

let button = UIButton()
button.setImage(UIImage(named: "home"), for: .normal)
button.sizeToFit()
button.translatesAutoresizingMaskIntoConstraints = false

tabBar.addSubview(button)
tabBar.centerXAnchor.constraint(equalTo: button.centerXAnchor).isActive = true
tabBar.topAnchor.constraint(equalTo: button.centerYAnchor).isActive = true

有时我还设置button.adjustsImageWhenHighlighted = false 来模仿其他项目的行为,或者更改约束constant 属性以向上或向下移动按钮。

【讨论】:

不明白这对标签栏是如何工作的?我现在需要一堆额外的代码来让按钮打开我想要的标签?【参考方案4】:

这是@Kakashi 答案的移植 Swift 3 版本(以及对他们的 +1),我将其放入我的自定义 UITabBarController 子类中:

override func viewDidLoad() 
        if let newButtonImage = UIImage(named: "new__button") 
            self.addCenterButton(withImage: newButtonImage, highlightImage: newButtonImage)
        
 

 func handleTouchTabbarCenter(sender : UIButton)
 
    if let count = self.tabBar.items?.count
    
        let i = floor(Double(count / 2))
        self.selectedViewController = self.viewControllers?[Int(i)]
    
 

func addCenterButton(withImage buttonImage : UIImage, highlightImage: UIImage) 

        let paddingBottom : CGFloat = 10.0

        let button = UIButton(type: .custom)
        button.autoresizingMask = [.flexibleRightMargin, .flexibleTopMargin, .flexibleLeftMargin, .flexibleBottomMargin]
        button.frame = CGRect(x: 0.0, y: 0.0, width: buttonImage.size.width / 2.0, height: buttonImage.size.height / 2.0)
        button.setBackgroundImage(buttonImage, for: .normal)
        button.setBackgroundImage(highlightImage, for: .highlighted)

        let rectBoundTabbar = self.tabBar.bounds
        let xx = rectBoundTabbar.midX
        let yy = rectBoundTabbar.midY - paddingBottom
        button.center = CGPoint(x: xx, y: yy)

        self.tabBar.addSubview(button)
        self.tabBar.bringSubview(toFront: button)

        button.addTarget(self, action: #selector(handleTouchTabbarCenter), for: .touchUpInside)

        if let count = self.tabBar.items?.count
        
            let i = floor(Double(count / 2))
            let item = self.tabBar.items![Int(i)]
            item.title = ""
        
    

【讨论】:

未调用按钮点击函数handleTouchTabbarCenter。 是的。相同的。有新的解决方案吗?? 问题:设备旋转,按钮位置不跟随。还有许多其他情况,按钮被重绘并且旧按钮仍然存在。如通话状态栏 嗨,谢谢,我确实看到了我的按钮,但是没有调用 handleTouchTabbarCenter,我们可能缺少什么(我看到有更多人遇到相同的错误)【参考方案5】:

我关注了@Michael Dautermann 的回答,但该按钮从未注册过点击,因此我对其进行了修改以使其正常工作:

  func handleTouchTabbarCenter()

    if let count = self.tabBar.items?.count
    
        let i = floor(Double(count / 2))
        self.selectedViewController = self.viewControllers?[Int(i)]
    


func addCenterButton(withImage buttonImage : UIImage, highlightImage: UIImage) 

    self.centerButton = UIButton(type: .custom)
    self.centerButton?.autoresizingMask = [.flexibleRightMargin, .flexibleTopMargin, .flexibleLeftMargin, .flexibleBottomMargin]
    self.centerButton?.frame = CGRect(x: 0.0, y: 0.0, width: buttonImage.size.width, height: buttonImage.size.height)
    self.centerButton?.setBackgroundImage(buttonImage, for: .normal)
    self.centerButton?.setBackgroundImage(highlightImage, for: .highlighted)
    self.centerButton?.isUserInteractionEnabled = true

    let heightdif: CGFloat = buttonImage.size.height - (self.tabBar.frame.size.height);

    if (heightdif < 0)
        self.centerButton?.center = (self.tabBar.center)
    
    else
        var center: CGPoint = (self.tabBar.center)
        center.y = center.y - 24
        self.centerButton?.center = center
    

    self.view.addSubview(self.centerButton!)
    self.tabBar.bringSubview(toFront: self.centerButton!)

    self.centerButton?.addTarget(self, action: #selector(handleTouchTabbarCenter), for: .touchUpInside)

    if let count = self.tabBar.items?.count
    
        let i = floor(Double(count / 2))
        let item = self.tabBar.items![Int(i)]
        item.title = ""
    

【讨论】:

【参考方案6】:

为了隐藏UITabbar,我制作了自定义UITabbarController并插入了这个方法。

- (void)viewDidLoad

    [super viewDidLoad];
    [self addCenterButtonWithImage:[UIImage imageNamed:@"logo"] highlightImage:[UIImage imageNamed:@"logo"]];


- (void)addCenterButtonWithImage:(UIImage*)buttonImage highlightImage:(UIImage*)highlightImage

    float paddingBottom = 10;

    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin;
    button.frame = CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
    [button setBackgroundImage:buttonImage forState:UIControlStateNormal];
    [button setBackgroundImage:highlightImage forState:UIControlStateHighlighted];

    CGRect rectBoundTabbar = [self.tabBar bounds];
    float xx = CGRectGetMidX(rectBoundTabbar);
    float yy = CGRectGetMidY(rectBoundTabbar) - paddingBottom;
    button.center = CGPointMake(xx, yy);

    [self.tabBar addSubview:button];
    [self.tabBar bringSubviewToFront:button];

    // add handle
    [button addTarget:self action:@selector(handleTouchTabbarCenter:) forControlEvents:UIControlEventTouchUpInside];

    // hide title item menu
    NSInteger count = [self.tabBar.items count];
    NSInteger i = floor(count / 2.0);
    UITabBarItem *item = [self.tabBar.items objectAtIndex:i];
    [item setTitle:nil];



- (void)handleTouchTabbarCenter:(id)sender

    // go to some view

【讨论】:

【参考方案7】:

我采用了 Manuel 的示例(已接受的答案),并针对 iPhone X 的问题添加了对底部安全区域插图的调整。

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[button setBackgroundImage:highlightImage forState:UIControlStateHighlighted];

CGFloat heightDifference = buttonImage.size.height - self.tabBar.frame.size.height;
CGPoint center = self.tabBar.center;
if (heightDifference >= 0) 
    center.y = center.y - heightDifference/2.0;


if (@available(ios 11.0, *)) 
    UIWindow *window = UIApplication.sharedApplication.keyWindow;
    CGFloat bottomPadding = window.safeAreaInsets.bottom;
    center.y = center.y - bottomPadding;


[self.view addSubview:button];

【讨论】:

谢谢你,接受的答案是 2010 年的,所以很高兴看到新型号的更新修复 :)【参考方案8】:

对于斯威夫特

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (Int64)(2.0)), dispatch_get_main_queue(), 
            let button: UIButton = UIButton(type: .Custom)
            let win:UIWindow = UIApplication.sharedApplication().delegate!.window!!

            button.frame = CGRectMake(0.0, win.frame.size.height - 65, 55, 55)
            button.center = CGPoint(x:win.center.x , y: button.center.y)

            button.setBackgroundImage(UIImage(named: "Camera") , forState: .Normal)
            button.setBackgroundImage(UIImage(named: "Camera"), forState: .Highlighted)
            win.addSubview(button)
        );

【讨论】:

为什么要将按钮添加到应用程序的窗口中?将它添加到视图控制器的视图中,或者更好的是,添加到标签栏本身不是更有意义吗? 我有一些其他的要求,我必须像上面的代码一样添加。这是我的项目要求的测试代码。 对,它可以工作是有道理的,只是将按钮与其所属的视图关联起来似乎更有意义,而不是整个应用程序的窗口。 谁投反对票..请给出相同的理由。 问题是关于自定义UITabbar而不是在窗口中添加按钮。

以上是关于我们如何创建一个更大的中心 UITabBar 项的主要内容,如果未能解决你的问题,请参考以下文章

如何制作中心更大的旋转木马? (扑)

如何在 UITabBar 中显示六个 TabBarItem

iOS Swift 3:UICollectionView 水平中心和更大的单元格

UITabBar 宽度不随屏幕尺寸增加

UITabBar 获取选中项

在线性时间内将小的排序列表合并为更大的排序列表的算法,没有重复项