Swift CollectionViewCell 的框架与其 CollectionView 不同
Swift CollectionViewCell has different frame than its CollectionView
我有一个 CollectionView
,它填满了整个屏幕,具有水平 scrollDirection 并且启用了分页。它位于 NavigationController
内部,隐藏 navigationBar
。 CollectionViewCells
也有屏幕的高度。
我希望发生的事情:
每个单元格都会填满整个屏幕,当我滑动到 left/right 时,另一个单元格会出现并填满整个屏幕。
实际发生了什么:
细胞没有填满整个屏幕。单元格顶部和屏幕顶部边框之间有一点 space(大约 20 像素)。此外,单元格的底部(也是大约 20 像素)是 "under" 屏幕的底部边框。
我也收到警告:
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 值是错误的。
我已经尝试过的:
override shouldInvalidateLayoutForBoundsChange
到 return 正确。
如你所见here蓝色边框是collectionView的边框,红色边框是cell的边框。蓝色边框如我所料,但我希望红色边框与蓝色边框一样。
代码如下:
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")
}
}
锚点方法:
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({[=14=].isActive = true})
return anchors
}
}
集合视图自动设置为整体视图。如果您不设置任何行为,collectionView 的内容能够自动调整昆虫。在这种情况下,将自动调整设置为 false 以获得全屏视图。屏幕的顶部和底部有一个安全区域,用于通过凹口调整视图。
试试这个
collectionView?.contentInsetAdjustmentBehavior = .never
希望这会解决这个问题。
我有一个 CollectionView
,它填满了整个屏幕,具有水平 scrollDirection 并且启用了分页。它位于 NavigationController
内部,隐藏 navigationBar
。 CollectionViewCells
也有屏幕的高度。
我希望发生的事情:
每个单元格都会填满整个屏幕,当我滑动到 left/right 时,另一个单元格会出现并填满整个屏幕。
实际发生了什么:
细胞没有填满整个屏幕。单元格顶部和屏幕顶部边框之间有一点 space(大约 20 像素)。此外,单元格的底部(也是大约 20 像素)是 "under" 屏幕的底部边框。
我也收到警告:
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 值是错误的。
我已经尝试过的:
override shouldInvalidateLayoutForBoundsChange
到 return 正确。
如你所见here蓝色边框是collectionView的边框,红色边框是cell的边框。蓝色边框如我所料,但我希望红色边框与蓝色边框一样。
代码如下:
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")
}
}
锚点方法:
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({[=14=].isActive = true})
return anchors
}
}
集合视图自动设置为整体视图。如果您不设置任何行为,collectionView 的内容能够自动调整昆虫。在这种情况下,将自动调整设置为 false 以获得全屏视图。屏幕的顶部和底部有一个安全区域,用于通过凹口调整视图。
试试这个
collectionView?.contentInsetAdjustmentBehavior = .never
希望这会解决这个问题。