- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建这个用户界面:
使用此代码:
extension String {
func style(_ attributes: [NSAttributedString.Key: Any]) -> NSAttributedString {
return NSAttributedString(string: self, attributes: attributes)
}
}
class ViewController: UIViewController {
private weak var newContainer: UIView?
private weak var newScrollContainer: UIScrollView?
private weak var newInputContainer: UIStackView?
private func addNewContainer() {
let container = UIView()
container.translatesAutoresizingMaskIntoConstraints = false
newContainer = container
view.addSubview(container)
container.topAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.topAnchor,
constant: 0).isActive = true
container.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
container.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10).isActive = true
container.heightAnchor.constraint(equalToConstant: 368).isActive = true
}
private func configureNewContainer() {
newContainer?.backgroundColor = UIColor(red: 188/255, green: 188/255, blue: 188/255, alpha: 1)
newContainer?.layer.borderColor = UIColor.black.cgColor
newContainer?.layer.borderWidth = 1
newContainer?.layer.cornerRadius = 6
newContainer?.layer.maskedCorners = [
.layerMaxXMaxYCorner,
.layerMaxXMinYCorner,
.layerMinXMaxYCorner,
.layerMinXMinYCorner]
}
private func addNewScrollContainer() {
guard let container = newContainer else { return }
let scroll = UIScrollView()
scroll.translatesAutoresizingMaskIntoConstraints = false
self.newScrollContainer = scroll
newContainer?.addSubview(scroll)
scroll.topAnchor.constraint(equalTo: container.topAnchor, constant: 75).isActive = true
scroll.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 28).isActive = true
scroll.trailingAnchor.constraint(
equalTo: container.trailingAnchor,
constant: 18).isActive = true
scroll.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: 36).isActive = true
}
private func addStack() {
let stack = UIStackView()
stack.translatesAutoresizingMaskIntoConstraints = false
stack.axis = .vertical
stack.spacing = UIStackView.spacingUseSystem
stack.distribution = .fillProportionally
self.newInputContainer = stack
newScrollContainer?.addSubview(stack)
newScrollContainer?.topAnchor.constraint(equalTo: stack.topAnchor, constant: 0).isActive = true
newScrollContainer?.leadingAnchor.constraint(equalTo: stack.leadingAnchor, constant: 0).isActive = true
newScrollContainer?.trailingAnchor.constraint(equalTo: stack.trailingAnchor, constant:0).isActive = true
newScrollContainer?.bottomAnchor.constraint(equalTo: stack.bottomAnchor, constant: 0).isActive = true
}
private func addStackControls() {
guard let container = newInputContainer else { return }
let red: [NSAttributedString.Key: Any] = [.foregroundColor: UIColor.red]
let dest = UITextField()
dest.attributedPlaceholder = "destination".style(red)
let cost = UITextField()
cost.attributedPlaceholder = "cost".style(red)
let pets = UITextField()
pets.attributedPlaceholder = "pets".style(red)
let people = UITextField()
people.attributedPlaceholder = "people".style(red)
let horizDivider = UIView()
horizDivider.backgroundColor = UIColor.black
horizDivider.heightAnchor.constraint(equalToConstant: 1).isActive = true
let width = container.frame.size.width*0.85
horizDivider.widthAnchor.constraint(equalToConstant: width).isActive = true
let origin = UITextField()
origin.attributedPlaceholder = "origin".style(red)
let departure = UITextField()
departure.attributedPlaceholder = "departure".style(red)
let note = UITextField()
note.attributedPlaceholder = "note".style(red)
let help = UIButton()
help.heightAnchor.constraint(equalToConstant: 26).isActive = true
help.widthAnchor.constraint(equalToConstant: 26).isActive = true
help.layer.cornerRadius = 13
help.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]
help.backgroundColor = UIColor.gray
help.layer.borderColor = UIColor.darkGray.cgColor
help.layer.borderWidth = 1
help.setAttributedTitle("?".style([.foregroundColor: UIColor.white]), for: .normal)
let vertDivider = UIView()
vertDivider.backgroundColor = UIColor.gray
vertDivider.widthAnchor.constraint(equalToConstant: 1).isActive = true
vertDivider.heightAnchor.constraint(equalToConstant: 25).isActive = true
let save = UIButton()
save.heightAnchor.constraint(equalToConstant: 35).isActive = true
save.widthAnchor.constraint(equalToConstant: 91).isActive = true
save.layer.cornerRadius = 6
save.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]
save.layer.borderWidth = 1
save.layer.borderColor = UIColor.white.cgColor
save.backgroundColor = .clear
let costPetsPeople = UIStackView(arrangedSubviews: [cost, pets, people])
costPetsPeople.spacing = UIStackView.spacingUseSystem
costPetsPeople.distribution = .fillEqually
costPetsPeople.axis = .horizontal
let originDeparture = UIStackView(arrangedSubviews: [origin, departure])
originDeparture.spacing = UIStackView.spacingUseSystem
originDeparture.distribution = .fillEqually
costPetsPeople.axis = .horizontal
let helpDividerSave = UIStackView(arrangedSubviews: [help, vertDivider, save])
helpDividerSave.distribution = .fillProportionally
helpDividerSave.axis = .horizontal
[dest, costPetsPeople, horizDivider, originDeparture, note, helpDividerSave].forEach {
newInputContainer?.addArrangedSubview($0)
}
}
override func viewDidLoad() {
super.viewDidLoad()
addNewContainer()
configureNewContainer()
addNewScrollContainer()
addStack()
addStackControls()
view.backgroundColor = UIColor(red: 206/255, green: 196/255, blue: 163/255, alpha: 1)
}
}
但我明白了:
感谢您的阅读,希望对您有所帮助:)。
最佳答案
情侣笔记...
使用 guard
展开对象以避免出现以下情况:newContainer?.layer.borderWidth = 1
一次从一个元素开始...如果您看不到“目标”文本字段,您可能也看不到其他任何内容。当您添加每个附加元素时,很容易看到某些内容是否被丢弃。
使用“批量”约束添加,并对它们进行逻辑分组。只是让阅读和跟踪正在发生的事情变得更容易。
提供对比背景颜色的 View ,以便更轻松地查看框架的走向。
这是你修改后的代码...你仍然需要调整一些东西才能得到你想要的东西,但这应该会让你上路(很多评论可以帮助你了解我做了什么):
extension String {
func style(_ attributes: [NSAttributedString.Key: Any]) -> NSAttributedString {
return NSAttributedString(string: self, attributes: attributes)
}
}
class PanelViewController: UIViewController {
private weak var newContainerView: UIView?
private weak var newScrollView: UIScrollView?
private weak var newInputStackView: UIStackView?
private func addNewContainer() {
let container = UIView()
container.translatesAutoresizingMaskIntoConstraints = false
newContainerView = container
view.addSubview(container)
NSLayoutConstraint.activate([
container.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0),
container.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
container.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
container.heightAnchor.constraint(equalToConstant: 368),
])
}
private func configureNewContainer() {
guard let container = newContainerView else { return }
container.backgroundColor = UIColor(red: 188/255, green: 188/255, blue: 188/255, alpha: 1)
container.layer.borderColor = UIColor.black.cgColor
container.layer.borderWidth = 1
container.layer.cornerRadius = 6
container.layer.maskedCorners = [
.layerMaxXMaxYCorner,
.layerMaxXMinYCorner,
.layerMinXMaxYCorner,
.layerMinXMinYCorner]
}
private func addNewScrollContainer() {
guard let container = newContainerView else { return }
let scroll = UIScrollView()
scroll.translatesAutoresizingMaskIntoConstraints = false
self.newScrollView = scroll
container.addSubview(scroll)
NSLayoutConstraint.activate([
scroll.topAnchor.constraint(equalTo: container.topAnchor, constant: 75),
scroll.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 28),
scroll.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -18),
scroll.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -36),
])
}
private func addStack() {
let stack = UIStackView()
stack.translatesAutoresizingMaskIntoConstraints = false
stack.axis = .vertical
stack.spacing = UIStackView.spacingUseSystem
stack.distribution = .fill
self.newInputStackView = stack
guard let nsc = newScrollView else { return }
nsc.addSubview(stack)
NSLayoutConstraint.activate([
stack.topAnchor.constraint(equalTo: nsc.topAnchor, constant: 0.0),
stack.leadingAnchor.constraint(equalTo: nsc.leadingAnchor, constant: 0.0),
stack.trailingAnchor.constraint(equalTo: nsc.trailingAnchor, constant: 0.0),
stack.bottomAnchor.constraint(equalTo: nsc.bottomAnchor, constant: 0.0),
])
}
private func addStackControls() {
// unwrap here to avoid the need for "?"
guard let inputStackView = newInputStackView,
let theScrollView = newScrollView
else { return }
let red: [NSAttributedString.Key: Any] = [.foregroundColor: UIColor.red]
let dest = UITextField()
dest.attributedPlaceholder = "destination".style(red)
let cost = UITextField()
cost.attributedPlaceholder = "cost".style(red)
let pets = UITextField()
pets.attributedPlaceholder = "pets".style(red)
let people = UITextField()
people.attributedPlaceholder = "people".style(red)
let horizDivider = UIView()
horizDivider.backgroundColor = UIColor.black
// to get the horizDivider centered we need to embed it
// in a "containing" view
let horizDividerContainingView = UIView()
horizDividerContainingView.addSubview(horizDivider)
let origin = UITextField()
origin.attributedPlaceholder = "origin".style(red)
let departure = UITextField()
departure.attributedPlaceholder = "departure".style(red)
let note = UITextField()
note.attributedPlaceholder = "note".style(red)
let help = UIButton()
help.layer.cornerRadius = 13
help.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]
help.backgroundColor = UIColor.gray
help.layer.borderColor = UIColor.darkGray.cgColor
help.layer.borderWidth = 1
help.setAttributedTitle("?".style([.foregroundColor: UIColor.white]), for: .normal)
let vertDivider = UIView()
vertDivider.backgroundColor = UIColor.gray
let save = UIButton()
save.layer.cornerRadius = 6
save.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]
save.layer.borderWidth = 1
save.layer.borderColor = UIColor.white.cgColor
save.backgroundColor = .clear
save.setTitle("save", for: .normal)
// horizontal stack view for cost / pets / people fields
let costPetsPeople = UIStackView(arrangedSubviews: [cost, pets, people])
costPetsPeople.spacing = UIStackView.spacingUseSystem
costPetsPeople.distribution = .fillEqually
costPetsPeople.axis = .horizontal
// horizontal stack view for origin / departure fields
let originDeparture = UIStackView(arrangedSubviews: [origin, departure])
originDeparture.spacing = UIStackView.spacingUseSystem
originDeparture.distribution = .fillEqually
costPetsPeople.axis = .horizontal
// horizontal stack view for help / save buttons fields
let helpDividerSave = UIStackView(arrangedSubviews: [help, vertDivider, save])
helpDividerSave.spacing = UIStackView.spacingUseSystem
helpDividerSave.distribution = .fill
helpDividerSave.axis = .horizontal
// to get the buttons stack view "right-aligned" we need to embed it
// in a "containing" view
let helpDividerSaveContainingView = UIView()
helpDividerSaveContainingView.addSubview(helpDividerSave)
// add elements to the vertical "input" stack view
[dest, costPetsPeople, horizDividerContainingView, originDeparture, note, helpDividerSaveContainingView].forEach {
inputStackView.addArrangedSubview($0)
}
// make sure everything has translatesAutoresizingMaskIntoConstraints = false
[dest, cost, pets, people, horizDivider, horizDividerContainingView,
origin, departure, note, help, vertDivider, save,
costPetsPeople, originDeparture, helpDividerSave, helpDividerSaveContainingView,
].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
}
// set all the textField backgrounds to white
[dest, cost, pets, people, origin, departure, note].forEach {
$0.backgroundColor = .white
}
// setup all the elements' constraints here
NSLayoutConstraint.activate([
// we want the vertical "input" stack view to take up the full width
// of the scroll view
inputStackView.widthAnchor.constraint(equalTo: theScrollView.widthAnchor, constant: 0.0),
// horizontal divider 1-pt height, 85% width, centered in its containing view
horizDivider.heightAnchor.constraint(equalToConstant: 1),
horizDivider.widthAnchor.constraint(equalTo: horizDividerContainingView.widthAnchor, multiplier: 0.85),
horizDivider.centerXAnchor.constraint(equalTo: horizDividerContainingView.centerXAnchor, constant: 0.0),
// help button 26 x 26 pts
help.heightAnchor.constraint(equalToConstant: 26),
help.widthAnchor.constraint(equalToConstant: 26),
// save button 91-pts wide
save.widthAnchor.constraint(equalToConstant: 91),
// vertical divider 1-pt width
vertDivider.widthAnchor.constraint(equalToConstant: 1),
// buttons stack view constrained "right-aligned" to its containing view
helpDividerSave.topAnchor.constraint(equalTo: helpDividerSaveContainingView.topAnchor, constant: 0.0),
helpDividerSave.trailingAnchor.constraint(equalTo: helpDividerSaveContainingView.trailingAnchor, constant: 0.0),
helpDividerSave.bottomAnchor.constraint(equalTo: helpDividerSaveContainingView.bottomAnchor, constant: 0.0),
])
}
override func viewDidLoad() {
super.viewDidLoad()
addNewContainer()
configureNewContainer()
addNewScrollContainer()
addStack()
addStackControls()
view.backgroundColor = UIColor(red: 206/255, green: 196/255, blue: 163/255, alpha: 1)
}
}
结果:
关于ios - 以编程方式在 UIScrollView 中使用 UIStackView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56622671/
我有一个很大的 CustomView,我在上面放置了一个父 UIStackView 以包含两个 UIStackView。 每个 UIStackView 都设置为包含两个项目,每个项目均等填充。 第一个
我正在尝试使用嵌入式 UIStackViews 来获得如下所示的内容: Label1 ----------------Label2 Label3 -- 所以我在一个水平 UIStackView 中有
前言:我偷看了this post它并没有解决我的问题。这是一个 link to a repo这显示了我遇到的错误。 我有一个 UIViewController 和一个包含嵌套水平 UIStackVie
在上面的屏幕中,您可以看到我正在使用 UIStackView 来垂直填充单选按钮。问题是当我使用 stackV.alignment = .leading 时,我的单选按钮没有利用 UIStackVie
我想问一下 UIStackView() 和 UIStackView(frame: .zero) 初始化程序之间的区别。 我想知道这两者中的哪一个是由 UIStackView() 默认触发的。 @int
问题:图像占用了大部分堆栈,文本缩小了 我尝试更改内容拥抱优先级但没有任何更改! 如何使用 storyboard 在 UIStackview 中做到这一点? 我希望单元格看起来像 Eventbrigh
我正在尝试制作一个比使用 UICollectionView 更容易制作网格的 UIControl 来执行某些小任务。我正在使用 UIStackViews 的 UIStackView。那是垂直堆栈(列)
我有一个嵌套的 UIStackView,当我按下一个按钮时,它就会被实例化。更详细地说,我有一个 UIStackView,它遍历一个充满 CustomUIStackViews 的 NSMutableA
我目前正在尝试制作一个简单的应用程序,该应用程序将根据用户输入显示少量内容。目前,我的屏幕上有一个堆栈 View ,里面有一个 UIView。我试图做到这一点,一旦按下一个按钮,UIView 就会消失
https://spin.atomicobject.com/2017/02/20/uistackview-stacking-child-views/ 我正在按照本教程获取 View 堆叠并使用它们的内
每个 View 都有一个进行渲染的层。令我困惑的是,您无法为堆栈 View 设置圆角半径或边框,但当您隐藏其中一个已排列的 subview 时,其余 subview 会填满堆栈 View 。 此外,A
我正在尝试在堆栈 View 中排列一组按钮。但是,当我使用 for-each 循环来执行此操作时,按钮最终会被一个放在另一个的顶部? var stackView: UIStackView = {
我正在尝试将 UIStackView 添加到我的窗口,但它没有显示。如下所示,我已经成功添加了 UINavigationBar。我还尝试添加各种其他控件,但实际上只出现了另一个 UIView。我已经附
我有一个 UIStackView (stack1),它包含两个排列的 View :一个 UIStackView (stack2) 和一个 UIScrollView (scroll) stack2 有固
我需要在水平 UIStackView 中有 X 个按钮,它位于 UIScrollView 中。要求是按钮应该均匀分布在堆栈 View 中,并且随着按钮数量的增加我应该减少间距以使它们适合屏幕的宽度,但
我有一个 UIScrollView 可以填充所有窗口并且包含一个垂直的 UIStackView 我想在其中添加 UILabels 以填充所有可用宽度. UIStackView 固定在 UIScroll
在使用平移手势移动 UIStackView 中的元素后,我试图获取/保留该元素的句柄。 例如,我试图捕获的元素是按钮标签或文本标签文本。 代码解释... 我正在通过函数 func createButt
我在 Storyboard中定义了一个 UIStackView,第一个按钮的高度设置为 70,其他按钮的高度设置为 45。我收到此自动布局错误: [LayoutConstraints] Unable
问题很简单——我真的很喜欢用 UIStackView 来组织 UI。但是,我在测试应用程序中看不到 UIStackView 边界。当 UI 元素不是预期的时候,我需要花很多时间来调试。在网上搜索,我找
我正在尝试将 UIButtons 动态添加到 UIStackView,但遇到了一些奇怪的行为。由于按钮内的文本也是动态的,因此它应该是多行的(默认情况下不是)。所以我这样设置中断模式: button
我是一名优秀的程序员,十分优秀!