Swift:带有中心圆形按钮的自定义 TabBar

2023-11-24

I try to create custom tabbar like the below picture: enter image description here

Below is the result i get: enter image description here

下面是我当前的代码:

class CustomTabBarController: UITabBarController {


    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()  
    }

    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 - 50
        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
    }

}

如何绘制第一个图片关节的选项卡栏的形状

我被困住了,非常感谢你的帮助


您需要自定义 Custom TabBarController 的选项卡栏

只需将 AppTabBar 分配给故事板的 tabBarController 的选项卡栏,如下所示 它应该有效

enter image description here

@IBDesignable
class AppTabBar: UITabBar {

    private var shapeLayer: CALayer?

    override func draw(_ rect: CGRect) {
        self.addShape()
    }

    private func addShape() {
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = createPath()
        shapeLayer.strokeColor = UIColor.lightGray.cgColor
        shapeLayer.fillColor = #colorLiteral(red: 0.9782002568, green: 0.9782230258, blue: 0.9782107472, alpha: 1)
        shapeLayer.lineWidth = 0.5
        shapeLayer.shadowOffset = CGSize(width:0, height:0)
        shapeLayer.shadowRadius = 10
        shapeLayer.shadowColor = UIColor.gray.cgColor
        shapeLayer.shadowOpacity = 0.3

        if let oldShapeLayer = self.shapeLayer {
            self.layer.replaceSublayer(oldShapeLayer, with: shapeLayer)
        } else {
            self.layer.insertSublayer(shapeLayer, at: 0)
        }
        self.shapeLayer = shapeLayer
    }

    func createPath() -> CGPath {
        let height: CGFloat = 86.0
        let path = UIBezierPath()
        let centerWidth = self.frame.width / 2
        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: (centerWidth - height ), y: 0))
        path.addCurve(to: CGPoint(x: centerWidth, y: height - 40),
                      controlPoint1: CGPoint(x: (centerWidth - 30), y: 0), controlPoint2: CGPoint(x: centerWidth - 35, y: height - 40))
        path.addCurve(to: CGPoint(x: (centerWidth + height ), y: 0),
                      controlPoint1: CGPoint(x: centerWidth + 35, y: height - 40), controlPoint2: CGPoint(x: (centerWidth + 30), y: 0))
        path.addLine(to: CGPoint(x: self.frame.width, y: 0))
        path.addLine(to: CGPoint(x: self.frame.width, y: self.frame.height))
        path.addLine(to: CGPoint(x: 0, y: self.frame.height))
        path.close()
        return path.cgPath
    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        guard !clipsToBounds && !isHidden && alpha > 0 else { return nil }
        for member in subviews.reversed() {
            let subPoint = member.convert(point, from: self)
            guard let result = member.hitTest(subPoint, with: event) else { continue }
            return result
        }
        return nil
    }
}

extension UITabBar {
    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = 74
        return sizeThatFits
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swift:带有中心圆形按钮的自定义 TabBar 的相关文章

随机推荐

  • 在 Ruby 中使用方法名称从字符串调用方法

    我怎样才能做到他们所说的here 但是在 Ruby 中呢 您将如何在对象上执行该功能 以及你将如何执行全局函数 请参阅 jetxee 的answer在提到的帖子上 示例代码 event name load def load puts loa
  • 如何重新渲染平面列表?

    与 ListView 不同的是 我们可以更新 this state datasource 有没有任何方法或示例来更新 FlatList 或重新渲染它 我的目标是当用户按下按钮时更新文本值 renderEntries item index r
  • 如何在 Visual Studio 代码中调试时扩展数组

    这是我的代码 它是一个简单的排列代码块 void arrange char c int N int start if start N print c N return for int i start i lt N i swap c star
  • iframe 滚动 iOS 8

    我有一个 iframe 我需要它有滚动溢出 它似乎可以在桌面上运行 我使用了一种解决方法使其可以在 iOS 中运行 现在它可以在 Android 和 iOS 上运行 然而 iOS8却失败了
  • 以编程方式映射 servlet,而不是使用 web.xml 或注释

    如何在没有 web xml 或注释的情况下以编程方式实现此映射 任务不是使用任何框架 如 spring 或其他框架
  • 使用 r 从字符串中提取电子邮件地址

    这是 5 个 Twitter 用户描述 这个想法是从每个字符串中提取电子邮件 这是我尝试过的代码 它有效 但可能有更好的东西 我宁愿避免使用 unlist 并使用正则表达式一次性完成它 我见过其他类似的 python perl php 问题
  • Spring MVC 类型转换:PropertyEditor 还是 Converter?

    我正在寻找在 Spring MVC 中绑定和转换数据的最简单的方法 如果可能的话 不做任何xml配置 到目前为止我一直在使用属性编辑器像这样 public class CategoryEditor extends PropertyEdito
  • PowerShell函数不会返回DataTable

    我在 PowerShell v4 0 Windows 7 x64 SP1 上有一个 PowerShell 脚本 它创建了一个非常复杂的数据表 我希望能够轻松地将 DataTable 代码放置在任何地方 因此我决定将其包装在一个简单的函数中
  • 数组通过 ajax post 被截断。 Ajax 发帖限制?

    我有一个多维数组 它由 426 个较小的数组组成 还包含 4 个属性 下面是 426 个数组之一的示例 array Main array 0 gt array 1 of 426 arrays name gt Danny email gt e
  • twitter-bootstrap 关闭警报不起作用

    我无法让它工作 当我单击关闭按钮时 什么也没有发生 这是代码 div class alert alert error alert block style width 200px div
  • 如何从另一个日期选择器中设置日期选择器中的最小日期?

    我目前正在向我的日期选择器添加验证 并且在设置最短日期时遇到问题to日期选择器是在中选择的任何内容from日期选择器 即 如果选择 12 3 15 则日期选择器中的最小日期为 12 3 15 这是我正在使用的代码 from datepick
  • 有时间限制的计算

    我正在尝试编写一个构造 它允许我在给定的时间窗口内运行计算 就像是 def expensiveComputation Double some intensive math val result Option Double timeLimit
  • 通过赋值运算符插入到 std::vector 的索引处

    我是 C 新手 很好奇这是否是插入 std vector 的首选方式 std vector
  • 在 OSX 上静态链接 gfortran 库的正确方法

    我有一个要分发的 Fortran 程序 因此我想静态链接到 gfortran 库 如果我使用以下标志编译程序 gfortran o myprog static libgfortran static libgcc myprog f otool
  • 将向量分割成块,使得每个块的总和近似恒定

    我有一个包含超过 100 000 条记录的大型数据框 其中的值已排序 例如 考虑以下虚拟数据集 df lt data frame values c 1 1 2 2 3 4 5 6 6 7 我想创建 3 组上述值 仅按顺序 以便每组的总和或多
  • 使用 WebDAV 访问 Exchange 2003 收件箱

    你怎么 使用 NET 使用 WebDAV 获取用户收件箱 不是您自己的收件箱 中的电子邮件列表 然后获取每封电子邮件的属性和 或内容 我想这样做而不WebDAV NET 如果可能的话 看看我的这篇关于 webdav 的帖子 希望它能给你一些
  • 实体框架循环引用

    再次尝试这个问题 因为我的第一次尝试几乎没有连贯性 p 所以我非常困惑并使用 Entity Framework Code First 我有一个森林课 我有一个树类 每个森林可以有很多树 当我尝试序列化时 我得到了循环引用 public cl
  • 将数组传递给构造函数而不声明它?

    在处理中 我定义了以下类 class SomeClass SomeClass int someArray println someArray 现在我想创建该类的实例 但在将数组传递给构造函数时遇到问题 SomeClass myVar new
  • 每 5 分钟运行一次 PHP 脚本并避免竞争条件

    我有一个 php 脚本 需要每 5 分钟运行一次 目前我正在使用 cron 作业来运行它 并且效果很好 但我的主机只允许最短时间 15 分钟 所以我的问题是 我可以使用访问者每5分钟触发一次php脚本的运行吗 我可以轻松地记录它上次运行的时
  • Swift:带有中心圆形按钮的自定义 TabBar

    I try to create custom tabbar like the below picture Below is the result i get 下面是我当前的代码 class CustomTabBarController UI