gpt4 book ai didi

ios - UIScrollView 内容布局不正确

转载 作者:行者123 更新时间:2023-11-28 23:20:58 25 4
gpt4 key购买 nike

我花了两天时间试图让它工作,但没有成功。我花了很多时间在这里和谷歌上进行研究,虽然有一些关于将 UIImageViews 添加到 UIScrollViews 的信息,但似乎没有太多关于 UITextFields 和 UILabels 等其他内容的信息。

引用下面的代码,我有几个问题:

  1. myScrollView 中的 contentView:即使 contentView 具有 backgroundColor、约束等,contentView 似乎没有正确显示,但添加到它的 subview 确实显示了(见附件截图)。
  2. 尽管设置了约束,但添加到 scrollViewcontentView 中的 UITextFields 布局不正确。从屏幕截图中可以看出,位于具有类似约束的那些 View 之外的文本字段确实得到了正确的布局 - 例如橙色文本字段。
  3. 垂直滚动无法显示(在本例中,thirdTextField,即蓝绿色文本字段)未显示且无法滚动到它。奇怪的是,如果我在 secondTextField 中键入内容,即红色文本字段,它将扩大大小并继续增长并最终自动激活 UIScrollView 的水平滚动。另外,不要将其理解为它嵌入到 containerView 中,该 View 具有似乎被忽略的约束。

对于 101 类型的问题,我们将不胜感激并提前致歉。

以下所有内容均以编程方式完成,而不是通过 Storyboard完成。

import UIKit

class ViewController: UIViewController {

lazy var myScrollView: UIScrollView = {
let view = UIScrollView(frame: .zero)
view.backgroundColor = .lightGray
return view
}()

lazy var contentView: UIView = {
let view = UIView()
view.backgroundColor = .blue
return view
}()

var firstTextField = UITextField()
var secondtextField = UITextField()
var thirdTextField = UITextField()
var fourthTextField = UITextField()

var firstLabel = UILabel()
var secondLabel = UILabel()

var aButton = UIButton()

var keyboardToolBar = UIToolbar()


override func viewDidLoad() {
super.viewDidLoad()

// Add first label
view.addSubview(firstLabel)
firstLabel.backgroundColor = .yellow
firstLabel.text = "Yellow Label"

// Layout first label
firstLabel.translatesAutoresizingMaskIntoConstraints = false
firstLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
firstLabel.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
firstLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20).isActive = true

// Add first textfield
view.addSubview(firstTextField)
firstTextField.backgroundColor = .orange
firstTextField.placeholder = "Orange TextField"

// Layout first text field
firstTextField.translatesAutoresizingMaskIntoConstraints = false
firstTextField.topAnchor.constraint(equalTo: view.topAnchor, constant: 150).isActive = true
firstTextField.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
firstTextField.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20).isActive = true
firstTextField.inputAccessoryView = keyboardToolBar

// Add scrollView
view.addSubview(myScrollView)

// Layout scrollview
myScrollView.translatesAutoresizingMaskIntoConstraints = false
myScrollView.topAnchor.constraint(equalTo: firstTextField.bottomAnchor, constant: 20).isActive = true
myScrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20.0).isActive = true
myScrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20.0).isActive = true
myScrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -200.0).isActive = true

// Add ContentView inside scrollview
myScrollView.addSubview(contentView)

// layout contentview
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.topAnchor.constraint(equalTo: myScrollView.topAnchor, constant: 20.0).isActive = true
contentView.leftAnchor.constraint(equalTo: myScrollView.leftAnchor, constant: 20.0).isActive = true
contentView.rightAnchor.constraint(equalTo: myScrollView.rightAnchor, constant: -20.0).isActive = true
contentView.bottomAnchor.constraint(equalTo: myScrollView.bottomAnchor, constant: -20.0).isActive = true

// Add secondTextfield - inside contentview
contentView.addSubview(secondtextField)
secondtextField.backgroundColor = .red
secondtextField.placeholder = "Red TextField"
secondtextField.inputAccessoryView = keyboardToolBar

// Layout secondtextField - inside contentview
secondtextField.translatesAutoresizingMaskIntoConstraints = false
secondtextField.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 100).isActive = true
secondtextField.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
secondtextField.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20).isActive = true

// Add thirdtextfield - inside contentview
contentView.addSubview(thirdTextField)
thirdTextField.backgroundColor = .brown
thirdTextField.placeholder = "Brown TextField"
thirdTextField.inputAccessoryView = keyboardToolBar

// Layout thirdtextField - inside contentview
thirdTextField.translatesAutoresizingMaskIntoConstraints = false
// Placed 500 below secondtextfield to use through vertical scrolling
thirdTextField.topAnchor.constraint(equalTo: secondtextField.topAnchor, constant: 500).isActive = true
thirdTextField.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
thirdTextField.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20).isActive = true

// elements outside of scrollview
// add fourthtextField
view.addSubview(fourthTextField)
fourthTextField.backgroundColor = .systemTeal
fourthTextField.placeholder = "Teal Textfield"
fourthTextField.inputAccessoryView = keyboardToolBar

// layout fourthtextField - over the top of the scrollview (for testing/modelling purposes)
fourthTextField.translatesAutoresizingMaskIntoConstraints = false
fourthTextField.topAnchor.constraint(equalTo: firstTextField.bottomAnchor, constant: 300).isActive = true
fourthTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
fourthTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10).isActive = true

// Add second label
view.addSubview(secondLabel)
secondLabel.backgroundColor = .green
secondLabel.text = "Green Label"

// Layout of second label
secondLabel.translatesAutoresizingMaskIntoConstraints = false
secondLabel.topAnchor.constraint(equalTo: view.bottomAnchor, constant: -150).isActive = true
secondLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
secondLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true

// Add button
view.addSubview(aButton)
aButton.backgroundColor = .systemBlue
aButton.setTitle("A Button", for: .normal)

// Layout button
aButton.translatesAutoresizingMaskIntoConstraints = false
aButton.topAnchor.constraint(equalTo: view.bottomAnchor, constant: -100).isActive = true
aButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
aButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true

// Add Target to BUtton
aButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)

}

}

enter image description here

最佳答案

Shurtugal 的回答部分正确——您需要在 thirdTextField 上添加一个 bottomAnchor 来给 contentView 一些高度:

thirdTextField.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true

有关其他讨论,请参阅对该答案的评论。

但是,我添加这个答案作为提示。如果您将约束逻辑地组合在一起,您可能会发现使用约束和自动布局要容易得多,如下面编辑过的代码所示:

class ViewController: UIViewController {

lazy var myScrollView: UIScrollView = {
let view = UIScrollView(frame: .zero)
view.backgroundColor = .lightGray
return view
}()

lazy var contentView: UIView = {
let view = UIView()
view.backgroundColor = .blue
return view
}()

var firstTextField = UITextField()
var secondtextField = UITextField()
var thirdTextField = UITextField()
var fourthTextField = UITextField()

var firstLabel = UILabel()
var secondLabel = UILabel()

var aButton = UIButton()

var keyboardToolBar = UIToolbar()

override func viewDidLoad() {
super.viewDidLoad()

// Add first label
view.addSubview(firstLabel)
firstLabel.backgroundColor = .yellow
firstLabel.text = "Yellow Label"

// Add first textfield
view.addSubview(firstTextField)
firstTextField.backgroundColor = .orange
firstTextField.placeholder = "Orange TextField"

firstTextField.inputAccessoryView = keyboardToolBar

// Add scrollView
view.addSubview(myScrollView)

// Add ContentView inside scrollview
myScrollView.addSubview(contentView)

// Add secondTextfield - inside contentview
contentView.addSubview(secondtextField)
secondtextField.backgroundColor = .red
secondtextField.placeholder = "Red TextField"
secondtextField.inputAccessoryView = keyboardToolBar

// Add thirdtextfield - inside contentview
contentView.addSubview(thirdTextField)
thirdTextField.backgroundColor = .brown
thirdTextField.placeholder = "Brown TextField"
thirdTextField.inputAccessoryView = keyboardToolBar

// elements outside of scrollview
// add fourthtextField
view.addSubview(fourthTextField)
fourthTextField.backgroundColor = .systemTeal
fourthTextField.placeholder = "Teal Textfield"
fourthTextField.inputAccessoryView = keyboardToolBar

// Add second label
view.addSubview(secondLabel)
secondLabel.backgroundColor = .green
secondLabel.text = "Green Label"

// Add button
view.addSubview(aButton)
aButton.backgroundColor = .systemBlue
aButton.setTitle("A Button", for: .normal)

[firstLabel, firstTextField, myScrollView, contentView, secondtextField, thirdTextField, fourthTextField, secondLabel, aButton].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
}

NSLayoutConstraint.activate([

// firstLabel 100-pts from top, 20-pts on each side
firstLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
firstLabel.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20),
firstLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20),

// firstTextField 150-pts from top, 20-pts on each side
firstTextField.topAnchor.constraint(equalTo: view.topAnchor, constant: 150),
firstTextField.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20),
firstTextField.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20),

// myScrollView 20-pts from bottom of firstTextField
// 20-pts on each side
// 200-pts from bottom of view
myScrollView.topAnchor.constraint(equalTo: firstTextField.bottomAnchor, constant: 20),
myScrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20.0),
myScrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20.0),
myScrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -200.0),

// contentView (subview of myScrollView) 20-pts on each side
// this will automatically define the scrollView's .contentSize
// however, it does NOT control the SIZE of contentView
contentView.topAnchor.constraint(equalTo: myScrollView.topAnchor, constant: 20.0),
contentView.leftAnchor.constraint(equalTo: myScrollView.leftAnchor, constant: 20.0),
contentView.rightAnchor.constraint(equalTo: myScrollView.rightAnchor, constant: -20.0),
contentView.bottomAnchor.constraint(equalTo: myScrollView.bottomAnchor, constant: -20.0),

// secondtextField (subview of contenView) 100-pts from top, 20-pts on each side
secondtextField.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 100),
secondtextField.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20),
secondtextField.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20),

// secondtextField (subview of contenView) 500-pts from top of secondtextField (should probably be from bottom of secondTextField)
// 20-pts on each side
// (end up being placed 500 below secondtextfield to use through vertical scrolling)
thirdTextField.topAnchor.constraint(equalTo: secondtextField.topAnchor, constant: 500),
thirdTextField.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20),
thirdTextField.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20),

// constraints which define the SIZE of contentView...

// if we want contentView to fit the width of myScrollView (with 20-pts "padding" on each side)
contentView.widthAnchor.constraint(equalTo: myScrollView.widthAnchor, constant: -40),
// thirdTextField bottom 20-pts from contentView bottom (this will define contentView's height)
thirdTextField.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -20),

// fourthTextField 300-pts from bottom of firstTextField, 10-pts on each side
fourthTextField.topAnchor.constraint(equalTo: firstTextField.bottomAnchor, constant: 300),
fourthTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
fourthTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),

// secondLabel 150-pts from bottom of view, 20-pts on each side
secondLabel.topAnchor.constraint(equalTo: view.bottomAnchor, constant: -150),
secondLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
secondLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),

// aButton 100-pts from bottom of view, 20-pts on each side
aButton.topAnchor.constraint(equalTo: view.bottomAnchor, constant: -100),
aButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
aButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),

])

// Add Target to BUtton
aButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)

}

@objc func buttonTapped() -> Void {
print("button tapped")
}

}

结果:

enter image description here

滚动后:

enter image description here

关于ios - UIScrollView 内容布局不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59679316/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com