【问题标题】:Can you give UIStackView borders?你能给 UIStackView 边框吗?
【发布时间】:2016-03-16 16:04:32
【问题描述】:

我试图在我的 ViewController 边框中提供 5 个单独的 UIStackViews。我给他们每个人一个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


    【解决方案1】:

    我在一个 UIStackView 中有多个 UIStackView。

    我只想要堆栈中的一个 UIStackViews 的顶部和底部边框,所以我将有问题的 UIStackView 添加到 UIView 中,背景颜色设置为我想要的顶部和底部边框颜色的颜色,并替换了带边框的UIStackView 在排列的Subviews 与 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()
        }
    

    【讨论】:

      【解决方案2】:

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

      这是 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)
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

          正如其他人指出的那样,您不能这样做(有关详细信息,请参阅 Clafou 的答案)。

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

          【讨论】:

            【解决方案5】:

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

            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)
            

            来源:How to add only a TOP border on a UIButton?

            【讨论】:

            • 我在 UIStackView 上试过这个并试图给它顶部边框,但它不起作用
            • 使用 CALayer 是唯一的办法。
            【解决方案6】:

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

            导致这个结果:

            Here's a link to my github repo 这个例子,所以你可以看到故事板文件。

            【讨论】:

            • 糟糕,我打错了,fixed
            【解决方案7】:

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

            【讨论】:

              【解决方案8】:

              很遗憾,这是无法做到的。 UIStackView 是不寻常的,因为它是一个执行布局(使用自动布局约束)但不显示自身的“非渲染”视图。它有一个和所有 UIView 一样的层,但它被忽略了。

              参见“管理堆栈视图的外观”下的the Apple doc

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

              【讨论】:

              • 至于怎么加边框,比较麻烦,不能就这样。您必须添加另一个视图并使用布局约束。如果不成功,请尝试使用代码发布问题!
              猜你喜欢
              • 2012-08-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-11-26
              • 2011-08-13
              • 2013-05-15
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多