UICollectionViewCell 的 UiTextField,在 UICollectionViewController 中重叠
Posted
技术标签:
【中文标题】UICollectionViewCell 的 UiTextField,在 UICollectionViewController 中重叠【英文标题】:UICollectionViewCell's UiTextField, overlapping in UICollectionViewController 【发布时间】:2017-12-24 14:48:46 【问题描述】:我正在尝试设计一个多步骤注册菜单。为此,我将 UICollectionViewController 与屏幕大小的单元格一起使用。在这些单元格中,我有一个 UITextView 来提问和一个 UITextField 来收集答案。我还有一个 Page 对象,用于在设置时从 uicollectionviewcontroller 传递信息。 我现在遇到的问题是,在每 3 页之后,我从 3 页之前的 textField 输入重复,而不是显示占位符。我注意到另一个问题,单元格似乎只实例化了 3 次,而不是我有多少页的 6 次。实例化顺序也很奇怪。起初它会执行一次,然后单击按钮,再执行两次,然后再也不执行了。 如何解决这个问题,我真的很挣扎,我不知道出了什么问题。
这是我的代码:
import UIKit
class OnboardingPageViewCell: UICollectionViewCell
override init(frame: CGRect)
super.init(frame: frame)
print("made a page")
setupView()
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
var oboardingPage = NewOnboardingPage()
didSet
reload()
private var questionTextField: UITextView =
var q = UITextView()
q.textColor = UIColor.white
q.textAlignment = .left
q.font = UIFont(name: "Avenir-Black", size: 25)
q.isEditable = true
q.isScrollEnabled = false
q.backgroundColor = UIColor.black
q.translatesAutoresizingMaskIntoConstraints = false
print("made aquestion field")
return q
()
private var answerField : CustomTextField =
let tf = CustomTextField.nameField
print("made an answer field")
return tf
()
private func setupView()
backgroundColor = UIColor.white
addSubview(questionTextField)
questionTextField.topAnchor.constraint(equalTo: topAnchor, constant: 120).isActive = true
questionTextField.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
questionTextField.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.90).isActive = true
questionTextField.heightAnchor.constraint(equalToConstant: 90).isActive = true
addSubview(answerField)
answerField.topAnchor.constraint(equalTo: questionTextField.bottomAnchor, constant: 20).isActive = true
answerField.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
answerField.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.90).isActive = true
answerField.heightAnchor.constraint(equalToConstant: 90).isActive = true
private func reload()
questionTextField.text = oboardingPage.question
answerField.placeholder = oboardingPage.answerField
class NewOnboardingPage
var question : String?
var answerField : String?
import UIKit
class SignUpController: UICollectionViewController, UICollectionViewDelegateFlowLayout
private let cellId = "cellId"
private var pages = [NewOnboardingPage]()
override func viewDidLoad()
super .viewDidLoad()
setupSignUpControllerView()
addPages()
private func addPages()
let namePage = NewOnboardingPage()
namePage.question = "What's your name?"
namePage.answerField = "What's your name?"
pages.append(namePage)
let birthDayPage = NewOnboardingPage()
birthDayPage.question = "When's your birthdate?"
birthDayPage.answerField = "When's your birthdate?"
pages.append(birthDayPage)
let userNamePage = NewOnboardingPage()
userNamePage.question = "Choose a user name."
userNamePage.answerField = "Choose a user name."
pages.append(userNamePage)
let passWordPage = NewOnboardingPage()
passWordPage.question = "Set a password"
passWordPage.answerField = "Set a password"
pages.append(passWordPage)
let emailAuthPage = NewOnboardingPage()
emailAuthPage.question = "What's your email?"
emailAuthPage.answerField = "What's your email?"
pages.append(emailAuthPage)
let phoneNumberPage = NewOnboardingPage()
phoneNumberPage.question = "What's your phone number?"
phoneNumberPage.answerField = "What's your phone number?"
pages.append(phoneNumberPage)
private func setupSignUpControllerView()
collectionView?.backgroundColor = .white
collectionView?.register(OnboardingPageViewCell.self, forCellWithReuseIdentifier: cellId)
collectionView?.isPagingEnabled = true
collectionView?.isScrollEnabled = true
if let layout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
view.addSubview(nextButton)
nextButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 400).isActive = true
nextButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
nextButton.widthAnchor.constraint(equalToConstant: 250).isActive = true
nextButton.heightAnchor.constraint(equalToConstant: 60).isActive = true
private let nextButton: UIButton =
let button = UIButton(type: .system)
button.backgroundColor = UIColor.RED
button.setTitle("next", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.titleLabel?.font = UIFont(name: "Avenir-Black", size: 25)
button.layer.cornerRadius = 30
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(turnNextPage), for: .touchUpInside)
return button
()
@objc private func turnNextPage()
let visibleItems: NSArray = collectionView?.indexPathsForVisibleItems as! NSArray
let currentItem: IndexPath = visibleItems.object(at: 0) as! IndexPath
let nextItem: IndexPath = IndexPath(item: currentItem.item + 1, section: 0)
if nextItem.row < pages.count
collectionView?.scrollToItem(at: nextItem, at: .left, animated: true)
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return pages.count
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! OnboardingPageViewCell
cell.oboardingPage = pages[indexPath.item]
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: view.frame.width, height: view.frame.height)
import UIKit
class CustomTextField: UITextField, UITextFieldDelegate
convenience init()
self.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
self.allowsEditingTextAttributes = false
self.autocorrectionType = .no
self.tintColor = UIColor.RED
self.translatesAutoresizingMaskIntoConstraints = false
override func willMove(toSuperview newSuperview: UIView?)
addTarget(self, action: #selector(editingChanged), for: .editingChanged)
editingChanged(self)
@objc func editingChanged(_ textField: UITextField)
guard let text = textField.text else return
textField.text = String(text.prefix(30))
override func selectionRects(for range: UITextRange) -> [Any]
return []
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool
if action == #selector(paste(_:)) ||
action == #selector(cut(_:)) ||
action == #selector(copy(_:)) ||
action == #selector(select(_:)) ||
action == #selector(selectAll(_:))
return false
return super.canPerformAction(action, withSender: sender)
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! OnboardingPageViewCell
cell.answerField.text = nil
cell.oboardingPage = pages[indexPath.item]
return cell
【问题讨论】:
【参考方案1】:1- textFeild 显示相同的数据而不是 placeholder 因为单元格出队所以你必须挂钩这些属性并清除它们在 cellForRowAt 中的内容/p>
2- 实例化是 3 而不是 6 aslo cell dequeuing
解决:
将两个属性添加到您的模型 NewOnboardingPage 将它们命名为 currentQuestion 和 currentAnswer,并在用户输入并滚动到下一页时将它们保存在模型数组中,您应该将它们设为全局,以便在单元格内部和外部集合中访问当您在 cellForRowAt 中滚动时,将这些值添加到 textfeild 和 textView
【讨论】:
你的意思是 cellForItemAt?所以像这样吧,(最后编辑)?这有帮助,谢谢。我不知道出队。但问题是,现在我以前的数据被删除了,所以如果用户决定向后滑动并查看输入的内容,那一切都消失了。如何让它再次显示? 当用户点击下一页时获取textfeild和textview的当前内容并存储在模型数组的相应索引中,当他点击返回时重新加载表格 顺便说一句,为什么其他所有东西都出队了,但是 textField 呢?毕竟,我使用的是 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) 作为! OnboardingPageViewCell 您可能会在 cellForRowAt 中刷新它的占位符以上是关于UICollectionViewCell 的 UiTextField,在 UICollectionViewController 中重叠的主要内容,如果未能解决你的问题,请参考以下文章
向 UICollectionViewCell 添加圆角和阴影
XCTest 与自定义 UICollectionViewCell