能给UIStackView边框吗?

问题描述 投票:0回答:10

我试图在我的

UIStackViews
边框中给出 5 个单独的
ViewController
。 我给他们每个人一个
IBOutlet
,然后在
viewDidLoad
中调用他们来使用
layer
属性,但没有效果。 是否无法以编程方式给出堆栈视图边框?

代码:

@IBOutlet weak var stackView1: UIStackView!
@IBOutlet weak var stackView2: UIStackView!
@IBOutlet weak var stackView3: UIStackView!
@IBOutlet weak var stackView4: UIStackView!
@IBOutlet weak var stackView5: UIStackView!

override func viewDidLoad() {
    super.viewDidLoad()

    stackView1.layer.borderWidth = 5
    stackView2.layer.borderWidth = 5
    stackView3.layer.borderWidth = 5
    stackView4.layer.borderWidth = 5
    stackView5.layer.borderWidth = 5   
}
swift uistackview
10个回答
45
投票

不幸的是,这是无法做到的。 UIStackView 的不同寻常之处在于它是一个“非渲染”视图,它执行布局(使用自动布局约束)但不显示自身。它有一个像所有 UIView 一样的层,但它被忽略了。

请参阅 Apple 文档“管理堆栈视图的外观”:

UIStackView 是 UIView 的非渲染子类。它不是 提供自己的任何用户界面。相反,它只是管理 其排列视图的位置和大小。结果,一些属性 (如背景颜色)对堆栈视图没有影响。相似地, 您不能覆盖layerClass、drawRect:或drawLayer:inContext:


16
投票

可以通过将堆栈视图内的视图作为边框来做到这一点。这可能需要大量工作,并且可能在某些情况下不起作用或必须解决,因此可能不值得付出努力。您需要嵌套堆栈视图,以便可以在水平和垂直方向提供边框。在我的Bordered Stack Views 博客文章中,我对此进行了更详细的介绍。但基本上我有常规视图,其背景设置为我选择的颜色,并且根据堆栈视图轴的方向将高度或宽度约束设置为 1。以下是界面构建器中内置 2x2 网格的完整层次结构:

view hierarchy

导致这个结果:

enter image description here

这是此示例的我的 github 存储库的链接,以便您可以查看故事板文件。


12
投票

您可以将 stackView 嵌入到 UIView 中,然后设置该视图的边框(颜色、宽度等),然后将 stackView 约束到该 UIView,如上、左、右、高度。


6
投票

这是我找到并使用的一段方便的代码:

extension UIView {
    func addTopBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:0,y: 0, width:self.frame.size.width, height:width)
        self.layer.addSublayer(border)
    }

    func addRightBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x: self.frame.size.width - width,y: 0, width:width, height:self.frame.size.height)
        self.layer.addSublayer(border)
    }

    func addBottomBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:0, y:self.frame.size.height - width, width:self.frame.size.width, height:width)
        self.layer.addSublayer(border)
    }

    func addLeftBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:0, y:0, width:width, height:self.frame.size.height)
        self.layer.addSublayer(border)
    }

    func addMiddleBorderWithColor(color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x:self.frame.size.width/2, y:0, width:width, height:self.frame.size.height)
        self.layer.addSublayer(border)
    }
}

只需在任何视图上使用,如下所示:

bottomControls.addMiddleBorderWithColor(color: buttonBorderColor, width: 3.0)

来源:如何在 UIButton 上仅添加顶部边框?


3
投票

正如其他人所指出的,你不能这样做(详情请参阅 Clafou 的回答)。

但是,您可以做的是将您的堆栈视图嵌入到另一个 UIView 中;对封闭 UIView 的图层进行修改。


1
投票

我认为最简单的方法是不再使用高度/宽度等于 1 的标签或视图来表示边框,我的意思是它比通过使用堆栈视图本身的 SPACING 属性更容易。只需填充您的堆栈及其内容,然后将外部垂直堆栈的间距设置为一,也将内部水平堆栈的间距设置为一,您就可以获得完美的结果。最后,为了给边框赋予特定的颜色,我使用外部 stckview 的背景视图来维护它,它只是具有与您希望的边框相同的背景颜色堆栈的约束,想法是当您设置间距时,间距会采用后面视图的颜色堆栈,就是这样:D,请检查附图中的结果,如果有任何不清楚的地方请告诉我enter image description here


1
投票

我在一个 UIStackView 中有多个 UIStackView。

我只想要堆栈中的一个 UIStackViews 的顶部和底部边框,因此我将有问题的 UIStackView 添加到 UIView 中,并将背景颜色设置为我想要的顶部和底部边框颜色的颜色,并替换了有边框的 UIStackView与 UIView 一起排列的子视图。

import UIKit
import Foundation

let goldBorderedUIView = UIView()

lazy var mainStackView: UIStackView =
    {
        let mainStack = UIStackView(arrangedSubviews: [goldBorderedUIView, stack2, stack3, stack 4])

        mainStack.translatesAutoresizingMaskIntoConstraints = false
        mainStack.axis = .vertical
        mainStack.spacing = 0.5
        mainStack.distribution = .fillEqually
        return mainStack
    }()


     func setupBorderdStack() { 

     NSLayoutConstraint.activate([
        borderedStackView.leadingAnchor.constraint(equalTo: goldBorderedUIView.leadingAnchor),
        borderedStackView.topAnchor.constraint(equalTo: goldBorderedUIView.topAnchor, constant: 5),
        borderedStackView.trailingAnchor.constraint(equalTo: goldBorderedUIView.trailingAnchor),
        borderedStackView.bottomAnchor.constraint(equalTo: goldBorderedUIView.bottomAnchor, constant: -5)
     ])
    }

     override func viewDidLoad() {
     super.viewDidLoad()

     setupBorderdStack()
    }

1
投票

这样使用

loseWeight.layer.borderColor = UIColor.orange.cgColor
loseWeight.layer.borderWidth = 1

enter image description here


0
投票

我发现向 UIStackView 添加边框的最简单方法是扩展堆栈视图类,然后添加两个分层视图:底部的视图与堆栈视图的大小相同,顶部的视图使用 mask out边框内侧,稍小一些。

这是 Swift 5 中的扩展:

extension UIStackView {
    func addBorder(color: UIColor, backgroundColor: UIColor, thickness: CGFloat) {
        let insetView = UIView(frame: bounds)
        insetView.backgroundColor = backgroundColor
        insetView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        insertSubview(insetView, at: 0)

        let borderBounds = CGRect(
            x: thickness,
            y: thickness,
            width: frame.size.width - thickness * 2,
            height: frame.size.height - thickness * 2)

        let borderView = UIView(frame: borderBounds)
        borderView.backgroundColor = color
        borderView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        insertSubview(borderView, at: 0)
    }
}

然后通过这样的调用添加边框:

myStackView.addBorder(color: .lightGray, backgroundColor: .white, thickness: 2)

0
投票

* 2024 年更新 *

在 iOS 15、Swift 5 中:通常的边框属性可以工作

是的,向 UIStackView 应用边框很简单。就我而言,我有一个嵌套的 UIStackViews,我可以使用以下代码设置 borderColor、borderWidth 和cornerRadius:

   myStackView.borderColor = UIColor(red: 25.0/255.0, green: 24.0/255.0, blue: 35.0/255.0, alpha: 0.15)
   myStackView.borderWidth = 1.0
   myStackView.cornerRadius = 4.0

这就是堆栈视图内容周围空间

24px
的创建方式。

   let myStackView = [oneStack, twoStack, threeStack].stack(axis: .vertical, distribution: .fill, alignment: .fill, spacing: 16)
   myStackView.layoutMargins = UIEdgeInsets(top: 24, left: 24, bottom: 24, right: 24)
   myStackView.isLayoutMarginsRelativeArrangement = true

如果需要对上例中的

oneStack
等应用边框,只需要扩展逻辑即可设置
borderColor
borderWidth
cornerRadius

© www.soinside.com 2019 - 2024. All rights reserved.