gpt4 book ai didi

ios - Swift CollectionViewCell 的框架与其 CollectionView 不同

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

设置:
我有一个 CollectionView,它填满了整个屏幕,具有水平 scrollDirection 并且启用了分页。它位于带有隐藏的 navigationBarNavigationController 中。 CollectionViewCells 也有屏幕的高度。

我期望发生的事情:
每个单元格都会填满整个屏幕,当我向左/向右滑动时,另一个单元格会出现并填满整个屏幕。
如你所见here蓝色边框是 collectionView 的边框,红色边框是单元格的边框。蓝色边框是我期望的样子,但我希望红色边框像蓝色边框一样。

实际发生了什么:
细胞没有填满整个屏幕。单元格顶部和屏幕顶部边框之间有一点空间(大约 20 像素)。此外,单元格的底部(也是大约 20 像素)位于屏幕底部边框的“下方”。
我也收到警告:

The behavior of the UICollectionViewFlowLayout is not defined because:
the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.

所以单元格高度看起来是正确的,但 y 值是错误的。

我已经尝试过的:
覆盖 shouldInvalidateLayoutForBoundsChange 以返回 true。

代码如下:

class LoginController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, LoginControllerDelegate, UIGestureRecognizerDelegate {

lazy var loginCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.dataSource = self
cv.delegate = self
cv.isPagingEnabled = true
cv.layer.borderWidth = 1.0
cv.layer.borderColor = UIColor.blue.cgColor
return cv
}()

let introCellId = "IntroCellId"
let loginCellId = "LoginCellId"

let pages: [Page] = {
let firstPage = Page(title: String,
message: String,
imageName: String)

let secondPage = Page(title: String,
message: String,
imageName: String)

let thirdPage = Page(title: String,
message: String,
imageName: String)

return [firstPage, secondPage, thirdPage]
}()

override func viewDidLoad() {
super.viewDidLoad()

navigationController?.navigationBar.isHidden = true

view.addSubview(loginCollectionView)

registerCells()
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return pages.count + 1
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

if indexPath.item == pages.count {
let loginCell = collectionView.dequeueReusableCell(withReuseIdentifier: loginCellId, for: indexPath) as! LoginCell
loginCell.loginControllerDelegate = self
loginCell.layer.borderColor = UIColor.red.cgColor
loginCell.layer.borderWidth = 2.0
return loginCell
}

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: introCellId, for: indexPath) as! PageCell
let page = pages[indexPath.item]
cell.page = page
cell.layer.borderColor = UIColor.red.cgColor
cell.layer.borderWidth = 2.0
return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.loginCollectionView.frame.width, height: self.loginCollectionView.frame.height)
}
}

页面单元格:

class PageCell: UICollectionViewCell {

var page: Page? {
didSet {
guard let page = page
else {
return
}

imageView.image = UIImage(named: page.imageName)

let color = UIColor(white: 0.2, alpha: 1)

let attributedText = NSMutableAttributedString(string: page.title, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 18, weight: UIFont.Weight.medium), NSAttributedString.Key.foregroundColor: color])

attributedText.append(NSMutableAttributedString(string: "\n\n\(page.message)", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.medium), NSAttributedString.Key.foregroundColor: color]))

let paragraphStyle = NSMutableParagraphStyle()

paragraphStyle.alignment = .center

let length = attributedText.string.count

attributedText.addAttributes([NSAttributedString.Key.paragraphStyle: paragraphStyle], range: NSRange(location: 0, length: length))

textView.attributedText = attributedText
}
}

override init(frame: CGRect) {
super.init(frame: frame)

setupViews()
}

let imageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.backgroundColor = UIColor(displayP3Red: 139/255, green: 221/255, blue: 116/255, alpha: 1)
iv.clipsToBounds = true
return iv
}()

let textView: UITextView = {
let tv = UITextView()
tv.isEditable = false
tv.contentInset = UIEdgeInsets(top: 24, left: 0, bottom: 0, right: 0)
tv.textColor = UIColor(displayP3Red: 51/255, green: 51/255, blue: 51/255, alpha: 1)
return tv
}()

func setupViews() {

addSubview(imageView)
addSubview(textView)

_ = imageView.anchor(topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: screenWidth, heightConstant: (screenHeight) / 2)

_ = textView.anchor(imageView.bottomAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: screenWidth, heightConstant: (screenHeight) / 2)

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been impremented")
}
}

登录单元格:

class LoginCell: UICollectionViewCell {

let logoImageView: UIImageView = {
let image = UIImage(named: "logo green")
let imageView = UIImageView(image: image)
return imageView
}()

let emailTextField: UITextField = {
let textField = UITextField()
textField.placeholder = "E-Mail"
textField.layer.borderColor = UIColor.lightGray.cgColor
let border = CALayer()
border.frame = CGRect(x: 0, y: 40, width: UIScreen.main.bounds.width - 64, height: 2.0)
border.backgroundColor = UIColor(displayP3Red: 51/255, green: 51/255, blue: 51/255, alpha: 1).cgColor
textField.layer.addSublayer(border)
textField.keyboardType = .emailAddress
return textField
}()

let emailAlertLabel: UILabel = {
let label = UILabel()
label.text = "E-Mail-Adresse nicht gefunden"
label.textColor = .red
label.isHidden = true
return label
}()

let passwordTextField: UITextField = {
let textField = UITextField()
textField.placeholder = "Passwort"
textField.layer.borderColor = UIColor.lightGray.cgColor
let border = CALayer()
border.frame = CGRect(x: 0, y: 40, width: UIScreen.main.bounds.width - 64, height: 2.0)
border.backgroundColor = UIColor(displayP3Red: 51/255, green: 51/255, blue: 51/255, alpha: 1).cgColor
textField.layer.addSublayer(border)
textField.isSecureTextEntry = true
return textField
}()

let passwordAlertLabel: UILabel = {
let label = UILabel()
label.text = "Ungültiges Passwort"
label.textColor = .red
label.isHidden = true
return label
}()

lazy var forgotPasswordButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = .white
button.setTitle("Passwort vergessen?", for: .normal)
button.setTitleColor(UIColor(displayP3Red: 139/255, green: 221/255, blue: 116/255, alpha: 1), for: .normal)
button.addTarget(self, action: #selector(handleForgotPassword), for: .touchUpInside)
button.contentHorizontalAlignment = .left
return button
}()

lazy var loginButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = UIColor(displayP3Red: 139/255, green: 221/255, blue: 116/255, alpha: 1)
button.setTitle("Login", for: .normal)
button.setTitleColor(.white, for: .normal)
button.addTarget(self, action: #selector(checkUserData), for: .touchUpInside)
button.layer.cornerRadius = 25.0
return button
}()

weak var loginControllerDelegate: LoginControllerDelegate?

lazy var stayLoggedInSwitch: UISwitch = {
let loginSwitch = UISwitch(frame: CGRect(x: 150, y: 150, width: 0, height: 0))
loginSwitch.addTarget(self, action: #selector(LoginCell.handleStayLoggedInState(_:)), for: .valueChanged)
loginSwitch.setOn(false, animated: true)
return loginSwitch
}()

let stayLoggedInTextField: UITextField = {
let textField = UITextField()
textField.text = "Angemeldet bleiben"
textField.textColor = UIColor(displayP3Red: 51/255, green: 51/255, blue: 51/255, alpha: 1)
textField.isUserInteractionEnabled = false
return textField
}()

let registerLabel: UILabel = {
let label = UILabel()
label.text = "Sie haben noch keinen Account?"
label.textColor = .lightGray
label.backgroundColor = .white
label.font = label.font.withSize(13)
return label
}()

lazy var registerButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = .white
button.setTitle("Registrieren", for: .normal)
button.setTitleColor(UIColor(displayP3Red: 139/255, green: 221/255, blue: 116/255, alpha: 1), for: .normal)
button.addTarget(self, action: #selector(handleRegister), for: .touchUpInside)
button.contentHorizontalAlignment = .left
button.titleLabel?.font = button.titleLabel?.font.withSize(13)
return button
}()

override init(frame: CGRect) {
super.init(frame: frame)

setupViews()
}

func setupViews() {

addSubview(logoImageView)
addSubview(emailTextField)
addSubview(emailAlertLabel)
addSubview(passwordTextField)
addSubview(passwordAlertLabel)
addSubview(forgotPasswordButton)
addSubview(loginButton)
addSubview(stayLoggedInSwitch)
addSubview(stayLoggedInTextField)
addSubview(registerLabel)
addSubview(registerButton)

_ = logoImageView.anchor(centerYAnchor, left: nil, bottom: nil, right: nil, topConstant: -230, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 160, heightConstant: 160)
logoImageView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true

_ = emailTextField.anchor(logoImageView.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 35, leftConstant: 32, bottomConstant: 0, rightConstant: 32, widthConstant: 0, heightConstant: 50)

_ = emailAlertLabel.anchor(emailTextField.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 0, leftConstant: 32, bottomConstant: 0, rightConstant: 32, widthConstant: 0, heightConstant: 20)

_ = passwordTextField.anchor(emailAlertLabel.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 0, leftConstant: 32, bottomConstant: 0, rightConstant: 32, widthConstant: 0, heightConstant: 50)

_ = passwordAlertLabel.anchor(passwordTextField.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 0, leftConstant: 32, bottomConstant: 0, rightConstant: 32, widthConstant: 0, heightConstant: 20)

_ = forgotPasswordButton.anchor(passwordAlertLabel.bottomAnchor, left: leftAnchor, bottom: nil, right: nil, topConstant: 0, leftConstant: 32, bottomConstant: 0, rightConstant: 0, widthConstant: 200, heightConstant: 25)

_ = loginButton.anchor(forgotPasswordButton.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 4, leftConstant: 32, bottomConstant: 0, rightConstant: 32, widthConstant: 0, heightConstant: 50)

_ = stayLoggedInSwitch.anchor(loginButton.bottomAnchor, left: leftAnchor, bottom: nil, right: nil, topConstant: 16, leftConstant: 32, bottomConstant: 0, rightConstant: 0, widthConstant: 60, heightConstant: 50)

_ = stayLoggedInTextField.anchor(loginButton.bottomAnchor, left: stayLoggedInSwitch.rightAnchor, bottom: nil, right: rightAnchor, topConstant: 16, leftConstant: 0, bottomConstant: 0, rightConstant: 32, widthConstant: 0, heightConstant: 32)

_ = registerLabel.anchor(nil, left: leftAnchor, bottom: bottomAnchor, right: nil, topConstant: 0, leftConstant: 32, bottomConstant: 32, rightConstant: 0, widthConstant: 200, heightConstant: 25)

_ = registerButton.anchor(nil, left: registerLabel.rightAnchor, bottom: bottomAnchor, right: rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 32, rightConstant: 32, widthConstant: 0, heightConstant: 25)

emailTextField.addTarget(self, action: #selector(underlineTextFieldColor(sender:)), for: .editingDidBegin)
emailTextField.addTarget(self, action: #selector(underlineTextFieldDark(sender:)), for: .editingDidEnd)
passwordTextField.addTarget(self, action: #selector(underlineTextFieldColor(sender:)), for: .editingDidBegin)
passwordTextField.addTarget(self, action: #selector(underlineTextFieldDark(sender:)), for: .editingDidEnd)
}

@objc func underlineTextFieldDark(sender: UITextField) {
sender.layer.sublayers![0].backgroundColor = UIColor(displayP3Red: 51/255, green: 51/255, blue: 51/255, alpha: 1).cgColor
}

@objc func underlineTextFieldColor(sender: UITextField) {
sender.layer.sublayers![0].backgroundColor = UIColor(displayP3Red: 139/255, green: 221/255, blue: 116/255, alpha: 1).cgColor
}

@objc func handleLogin() {
loginControllerDelegate?.finishLoggingIn()
}

@objc func handleStayLoggedInState(_ sender: UISwitch) {
if (sender.isOn == true) {
UserDefaults.standard.setIsLoggedIn(value: true)
}
else {
UserDefaults.standard.setIsLoggedIn(value: false)
}
}

@objc func handleForgotPassword() {
loginControllerDelegate?.finishLoggingIn()
}

@objc func handleRegister() {
loginControllerDelegate?.finishLoggingIn()
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

anchor 方法:

extension UIView {

func anchor(_ top: NSLayoutYAxisAnchor? = nil, left: NSLayoutXAxisAnchor? = nil, bottom: NSLayoutYAxisAnchor? = nil, right: NSLayoutXAxisAnchor? = nil, topConstant: CGFloat = 0, leftConstant: CGFloat = 0, bottomConstant: CGFloat = 0, rightConstant: CGFloat = 0, widthConstant: CGFloat = 0, heightConstant: CGFloat = 0) -> [NSLayoutConstraint] {
translatesAutoresizingMaskIntoConstraints = false

var anchors = [NSLayoutConstraint]()

if let top = top {
anchors.append(topAnchor.constraint(equalTo: top, constant: topConstant))
}

if let left = left {
anchors.append(leftAnchor.constraint(equalTo: left, constant: leftConstant))
}

if let bottom = bottom {
anchors.append(bottomAnchor.constraint(equalTo: bottom, constant: -bottomConstant))
}

if let right = right {
anchors.append(rightAnchor.constraint(equalTo: right, constant: -rightConstant))
}

if widthConstant > 0 {
anchors.append(widthAnchor.constraint(equalToConstant: widthConstant))
}

if heightConstant > 0 {
anchors.append(heightAnchor.constraint(equalToConstant: heightConstant))
}

anchors.forEach({$0.isActive = true})

return anchors
}
}

最佳答案

Collection View 自动设置为整个 View 。如果您不设置任何行为,collectionView 的内容能够自动调整昆虫。在这种情况下,将自动调整设置为 false 以获得全屏 View 。屏幕的顶部和底部有一个安全区域,可以通过凹口调整 View 。

试试这个

collectionView?.contentInsetAdjustmentBehavior = .never

希望这会解决这个问题。

关于ios - Swift CollectionViewCell 的框架与其 CollectionView 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58234464/

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