我正在尝试在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
}
答案 0 :(得分:24)
不幸的是,这无法完成。 UIStackView很不寻常,因为它是一个非渲染的"执行布局的视图(使用自动布局约束)但不显示自身。它有一个像所有UIViews一样的层,但它被忽略了。
请参阅"管理堆栈视图的外观"下的the Apple doc:
UIStackView是UIView的非渲染子类。它不是 提供自己的任何用户界面。相反,它只是管理 其布置视图的位置和大小。结果,一些属性 (如backgroundColor)对堆栈视图没有影响。同样的, 你不能覆盖layerClass,drawRect:或drawLayer:inContext:
答案 1 :(得分:13)
可以通过在堆栈视图中查看边框来实现此目的。这可能是很多工作,可能会有某些情况要么无法工作,要么必须解决,因此可能不值得付出努力。您需要嵌套堆栈视图,以便在水平和垂直方向上提供边框。在我的Bordered Stack Views blog post中,我会详细介绍这一点。但基本上我有常规视图的背景设置为我选择的颜色,我根据堆栈视图的轴的方向给出高度或宽度约束1。以下是界面构建器中内置的2x2网格的完整层次结构:
导致此结果:
此示例的Here's a link to my github repo,以便您可以查看故事板文件。
答案 2 :(得分:8)
您可以在UIView中嵌入stackView,然后设置该视图的边框(颜色,宽度等),然后将stackView约束到UIView,如top,left,right,height。
答案 3 :(得分:1)
这是我找到并使用的一小段代码:
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)
答案 4 :(得分:1)
我发现向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)
答案 5 :(得分:1)
我在一个UIStackView中有多个UIStackViews。
我只想为堆栈中的一个UIStackViews设置上下边框,所以我将有问题的UIStackView添加到UIView中,背景色设置为我想要的上下边框颜色,并替换了边框带有UIView的rangedSubviews中的UIStackView。
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()
}
答案 6 :(得分:0)
正如其他人所指出的,您不能执行此操作(有关详细信息,请参阅Clafou的回答)。
但是,您可以做的是将堆栈视图嵌入另一个UIView中。对封闭的UIView层进行修改。
答案 7 :(得分:0)