如何使用Swift创建一个圆角标签?

3
我该如何在Swift中创建以下选项卡(见附件)? enter image description here

请查看 https://github.com/kirillgorbushko/HKAnimatedTabBar。 - hbk
另一个简单的例子:https://github.com/HappyIosDeveloper/SwiftUIAppWithCustomTabBar - Ahmadreza
5个回答

9

参考以下回答:https://dev59.com/brLma4cB1Zd3GeqPZVq8#58941827

如下所示,子类化UITabBar。这个解决方案考虑到了有刘海的设备的safeArea布局指南。我发现65是一个适合顶部圆角tabBar的高度。

@IBDesignable class TabBarWithCorners: UITabBar {
    @IBInspectable var color: UIColor?
    @IBInspectable var radii: CGFloat = 15.0

    private var shapeLayer: CALayer?

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

    private func addShape() {
        let shapeLayer = CAShapeLayer()

        shapeLayer.path = createPath()
        shapeLayer.strokeColor = UIColor.gray.withAlphaComponent(0.1).cgColor
        shapeLayer.fillColor = color?.cgColor ?? UIColor.white.cgColor
        shapeLayer.lineWidth = 2
        shapeLayer.shadowColor = UIColor.black.cgColor
        shapeLayer.shadowOffset = CGSize(width: 0   , height: -3);
        shapeLayer.shadowOpacity = 0.2
        shapeLayer.shadowPath =  UIBezierPath(roundedRect: bounds, cornerRadius: radii).cgPath
        

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

        self.shapeLayer = shapeLayer
    }

    private func createPath() -> CGPath {
        let path = UIBezierPath(
            roundedRect: bounds,
            byRoundingCorners: [.topLeft, .topRight],
            cornerRadii: CGSize(width: radii, height: 0.0))

        return path.cgPath
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        self.isTranslucent = true
        var tabFrame            = self.frame
        tabFrame.size.height    = 65 + (UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? CGFloat.zero)
        tabFrame.origin.y       = self.frame.origin.y +   ( self.frame.height - 65 - (UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? CGFloat.zero))
        self.layer.cornerRadius = 20
        self.frame            = tabFrame



        self.items?.forEach({ $0.titlePositionAdjustment = UIOffset(horizontal: 0.0, vertical: -5.0) })


    }

}

结果应该看起来像这样:2


3
非常好的答案!不过有一件事,虽然不是那么关键。那个烦人的“关键窗口”警告修复:只需将: UIApplication.shared.keyWindow?替换为: UIApplication.shared.windows.filter {$0.isKeyWindow}.first? - nja
好的答案!但是对于我的情况,圆角后面的区域是不透明的,无法看到下面的内容。我必须设置self.shadowImage = UIImage()和self.backgroundImage = UIImage(),这样由tabBar创建的背景视图自动变成完全透明。花了我两天时间才弄清楚,希望这能帮助到别人。 - Bruce
这个很好!你怎么把单独的图片向上移动?标题向上移动了,但现在离图标太近了。 - TrevPennington
这很好,但是不能正常工作,在角落上显示一些白色空间。如果我尝试在选项卡栏下方放置一些视图,它会用一些白色层覆盖它的角落。此外,它向上移动了很多。我原本使用14-16点的底部约束来设置按钮,现在选项卡栏正在触碰它们。 - Emm

4

我猜这是UITabBar,所以你可以像这样在某些代码中设置圆角:

layer.cornerRadius = 30
layer.masksToBounds = true
layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]

第一个控制四舍五入,而maskedCorners则指定仅圆角左上和右上角。
或者创建子类并在 init 中设置这些属性。

1
很简单,你可以像这样创建你的视图:

view

let theView: UIView = {
   let v = UIView()
   v.translatesAutoresizingMaskIntoConstraints = false
   v.backgroundColor = .white
   v.layer.cornerRadius = 30
   v.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
   return v
}()

您可以将cornerRadius更改为任何您喜欢的值。上面的代码使您的view在顶部具有圆角,就像您的图片中一样。

0

最好的方法是子类化UITabBar类,并在其中绘制您想要添加阴影的经典tabBar。 这里有一个不错的快速入门教程

如果您不需要完全控制,另一种解决方法是这样做

tabBar.layer.masksToBounds = true 
tabBar.isTranslucent = true  
tabBar.layer.cornerRadius = 10 
self.tabBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]

0

试试这个

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: view.frame.width, height: tabBar.frame.height), cornerRadius: 15)
    let mask = CAShapeLayer()
    mask.path = path.cgPath
    tabBar.layer.mask = mask

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接