前一段时间我问如何在this question中绘制UI块。感谢@HangarRash我得到了答案,并了解如何做到这一点。但现在我想创建StackView,这是基于其他两个stackview。我有这样的代码:
class ViewController: UIViewController {
@IBOutlet weak var mainContainer: UIView!
let colorDictionary = [
"Red":UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0),
"Green":UIColor(red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0),
"Blue":UIColor(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0),
// "Green2":UIColor(red: 1.0, green: 0.7, blue: 0.0, alpha: 1.0),
]
//MARK: Instance methods
func colorButton(withColor color:UIColor, title:String) -> UILabel{
let newButton = UILabel()
newButton.backgroundColor = .gray
newButton.text = title
newButton.textAlignment = .center
newButton.textColor = UIColor.white
return newButton
}
func displayKeyboard(){
var buttonArray = [UILabel]()
for (myKey,myValue) in colorDictionary{
buttonArray += [colorButton(withColor: myValue, title: myKey)]
}
let horizontalStack = UIStackView(arrangedSubviews: buttonArray)
horizontalStack.axis = .horizontal
horizontalStack.distribution = .fillEqually
horizontalStack.alignment = .fill
horizontalStack.translatesAutoresizingMaskIntoConstraints = false
let label2 = UILabel()
label2.text = "Label"
label2.backgroundColor = .red
label2.textColor = .white
label2.textAlignment = .center
label2.lineBreakMode = .byCharWrapping
label2.numberOfLines = 0
label2.translatesAutoresizingMaskIntoConstraints = false
let leftStack = UIStackView()
leftStack.backgroundColor = .blue
leftStack.axis = .vertical
leftStack.distribution = .equalSpacing
leftStack.translatesAutoresizingMaskIntoConstraints = false
leftStack.addArrangedSubview(label2)
leftStack.addArrangedSubview(horizontalStack)
leftStack.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
let bottomStackView = UIStackView(arrangedSubviews: buttonArray)
bottomStackView.axis = .horizontal
bottomStackView.distribution = .fillEqually
bottomStackView.alignment = .fill
let stackView = UIStackView()
stackView.axis = .vertical
stackView.translatesAutoresizingMaskIntoConstraints = false
let url = URL(string: "https://picsum.photos/270")!
let image = UIImageView()
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, _, error in
if let data = data {
DispatchQueue.main.async {
image.image = UIImage(data: data)
image.contentMode = .scaleToFill
image.translatesAutoresizingMaskIntoConstraints = false
}
}
}.resume()
stackView.addArrangedSubview(image)
stackView.addArrangedSubview(bottomStackView)
let mainStackView = UIStackView()
mainStackView.axis = .horizontal
mainStackView.addArrangedSubview(leftStack)
mainStackView.addArrangedSubview(stackView)
mainContainer.addSubview(mainStackView)
mainStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
mainStackView.topAnchor.constraint(equalTo: mainContainer.topAnchor, constant: 5),
mainStackView.leftAnchor.constraint(equalTo: mainContainer.leftAnchor),
mainStackView.rightAnchor.constraint(equalTo: mainContainer.rightAnchor),
mainStackView.heightAnchor.constraint(equalToConstant: 270),
leftStack.widthAnchor.constraint(equalToConstant: 270),
])
}
override func viewDidLoad() {
super.viewDidLoad()
displayKeyboard()
}
}
它给我画了这样一幅画面:
但是我不明白我的左UI块在哪里,有4个不同的标签,以及如何使stackview UI按比例填充。我的意思是,我不需要巨大的左视图,我需要它的10%左右的主stackview。我试图使它在这样的方式:
leftStack.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1).isActive = true
但这并没有帮助我。我需要像10%的左块和90%的主块与图像。我认为这是可能的设置比例为视图内的堆栈视图
2条答案
按热度按时间a8jjtwal1#
您遇到的问题与转换和自动布局如何交互有关--或者,也许更好地说,不交互。
来自Apple的docs:
在iOS 8.0及更高版本中,transform属性不影响自动布局。自动布局基于视图的未变换框架计算视图的对齐矩形。
因此,当旋转堆栈视图时,将使用其未变换帧。
举个简单的例子...让我们把三个标签放在一个水平堆栈视图中,并对中间的标签应用旋转变换:
我们得到的结果是:
第一节第一节第一节第一节第一次
有很多方法可以解决这个问题......考虑一下您的最终目标,让我们创建一个
UIView
子类,其中包含一个标签,当根据标签的框架进行转换时,它会自动调整自身。因此,自定义类:
和与
Step1
相同的控制器,但我们将使用三个MyCustomLabelView
,而不是三个UILabel
:现在,当我们旋转中心标签(视图)时,我们会得到:
第一节第二节第一节第三节第一节
因此,为了获得您想要的完整布局,我们将创建一个自定义视图,其中包含"左侧"标签(在两个堆栈视图中)、一个图像视图、一个底部标签的堆栈视图和一个"外部"堆栈视图,以将所有内容放在一起。
自定义"左侧"类:
以及示例控制器:
结果是:
为了稍微改善视觉效果,我想在标签上添加一些"填充"......因此,我使用了这个简单的标签子类:
将
colorLabel(...)
函数替换为:得到最终结果:
vdgimpew2#
首先,创建两个子堆栈视图,并根据需要配置它们。
接下来,创建水平堆栈视图,并将两个子堆栈视图添加为已排列的子视图:
最后,将水平堆栈视图添加到视图层次结构中,并根据需要配置其约束。例如:
这将创建一个水平堆栈视图,其中两个子堆栈视图并排排列,填充父视图的整个宽度。然后,您可以根据需要向子堆栈视图添加视图以创建布局。