Пара заметок ...
Используйте guard
, чтобы развернуть объекты, чтобы избежать таких вещей, как: newContainer?.layer.borderWidth = 1
Начинайте с одного элемента за раз ... если вы не видите текстовое поле вашего "назначения", вы, вероятно, больше ничего не увидите. Когда вы добавляете каждый дополнительный элемент, будет легко увидеть, когда что-то сбрасывается.
Используйте «пакетные» дополнения ограничений и сгруппируйте их логически. Просто облегчает чтение и отслеживание происходящего.
Придайте взглядам контрастные цвета фона, чтобы было легче видеть, куда движутся кадры.
Вот ваш модифицированный код ... у вас еще будет несколько настроек, чтобы получить именно то, что вы хотите, но это должно помочь вам (много комментариев, которые помогут вам увидеть, что я сделал):
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)
}
}
Результат: