自定义UItababbar Swift

问题描述

谁能指出我如何在UITabbar中实现这种设计。我曾尝试添加背景图片,但这看起来与设计不一样。这里的曲线超出了UITabbar的框架,不确定如何在活动选项卡顶部添加此视图。

Tab bar with a curved top

解决方法

UITabBarController创建自定义TabBar可以解决此问题。不用将直接图像添加到标签栏,而应使用UIGraphicsBeginImageContext用于selectedTabBackgroundImage的即时图像。

  1. 创建图像。
  2. 将图像的顶部切成圆形

这是代码示例。

import UIKit

class CustomTabBarViewController: UITabBarController {
    
    var topClipSize: CGFloat = 24.5 //Adjust based on the number of tabbar
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let singleTabWidth: CGFloat = self.tabBar.frame.size.width / CGFloat((self.tabBar.items?.count)!)
        let singleTabSize = CGSize(width:singleTabWidth,height: self.tabBar.frame.size.height)
        // Create the backgound image
        let selectedTabBackgroundImage: UIImage = self.imageWithColor(color: .blue,size: singleTabSize)
        // Clip the top
        self.tabBar.selectionIndicatorImage = selectedTabBackgroundImage.roundTopImage(topClipSize: topClipSize)
    }
    
    func imageWithColor(color: UIColor,size: CGSize) -> UIImage {
        if size.height > 55 {
            topClipSize = 30.0  // iPhone 8 tabbar height is 53 and iPnone X is 83 - We need more space on top.
        }
        let rect = CGRect(x: 0,y: 0,width: size.width,height: size.height + topClipSize)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context!.setFillColor(color.cgColor)
        context!.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image!
    }
}

extension UIImage {
    func roundTopImage(topClipSize: CGFloat) -> UIImage {
    let rect = CGRect(origin:CGPoint(x: 0,y: 0),size: self.size)
    let rectBounds: CGRect = CGRect(x: rect.origin.x,y: rect.origin.y + (topClipSize * 2),width: rect.size.width,height: rect.size.height - (topClipSize * 2))
    let ovalBounds: CGRect = CGRect(x: rect.origin.x - topClipSize,y: rect.origin.y,width: rect.size.width + (topClipSize * 2),height: rect.size.height)
    UIGraphicsBeginImageContextWithOptions(self.size,false,1)
    let rectPath = UIBezierPath(rect: rectBounds)
    let ovalPath = UIBezierPath(ovalIn: ovalBounds)
    rectPath.append(ovalPath)
    rectPath.addClip()
    self.draw(in: rect)
    return UIGraphicsGetImageFromCurrentImageContext()!
}
}

以下是输出:

enter image description here

,

实际上不可能优雅地更改本机UITabBar的外观。您的选择是创建一个行为类似于UITabBarController的自定义容器视图控制器,或者只是隐藏默认选项卡栏并在该空间中实现自己的视图。

尽管它不太优雅,因为您只是将视图放在默认选项卡栏的顶部,但实际上我喜欢这种方法,因为您保留了本机UITabBarController的优点(从其视图控制器调用self.tabBarController ?,它已经调整了布局边距,等等。

为此,在UITabBarController的子类中隐藏tabBar:

self.tabBar.isHidden = true
self.tabBar.alpha = 0

然后在实现所需的自定义视图之后,只需在viewDidLayoutSubviews中将自定义视图的框架设置为self.tabBar.frame。

要更改viewController,请在用户点击您的自定义标签之一时调用此方法:

self.selectedIndex = newIndex