我根据数组textField
中提供的元素在表视图的单元格中获取小部件textView
或widgetInstockArray
。
并从labelInstcokArray
问题:单元格出现时两个窗口小部件重叠,textField包含在每个单元格的textView中。
我想要的是:每个单元格中应该有一个textField或textView,但不是封闭的和&同时重叠。
这是我到目前为止所做的:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextViewDelegate {
var widgetInstockArray = [String]()
var labelInstockArray = [String]()
var idInstockArray = [IntegerLiteralType]()
var newLabel = UITextField()
var newTextView = UITextView()
let wTextField = "textField"
let wTextView = "textView"
@IBOutlet weak var firstTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
widgetInstockArray = [wTextView, wTextField, wTextView, wTextField, wTextField, wTextView, wTextField]
idInstockArray = [1,2,3,4,5,6,7]
labelInstockArray = ["1ok","2ok","3ok","4ok","5ok","6ok","7ok"]
firstTableView.delegate = self
firstTableView.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return widgetInstockArray.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var Cell : UITableViewCell?
var instockTag : Int = 1
Cell = firstTableView.dequeueReusableCell(withIdentifier: "firstCell")! as UITableViewCell
if widgetInstockArray.count == 0 && labelInstockArray.isEmpty {
print("no textFields in instock")
}
else {
print("widget process i in winstock loop")
for i in widgetInstockArray {
print("widget process i in winstock loopok so here is \(i)")
let indexOfA = widgetInstockArray.index(of: i)
print("her is the index of i of widgets \(String(describing: indexOfA))")
if i.contains(wTextField) {
print("textField was placed")
newLabel = UITextField(frame: CGRect(x: 10, y: 10, width: 200, height: 30))
newLabel.textColor = UIColor.gray
newLabel.tag = instockTag
print("You have a instock textLabel with tag \(newLabel.tag)")
if labelInstockArray.isEmpty || idInstockArray.count != labelInstockArray.count {
newLabel.text = " "
} else {
newLabel.placeholder = labelInstockArray[indexPath.row]
newLabel.layer.cornerRadius = 3
newLabel.layer.borderColor = UIColor.gray.cgColor
newLabel.layer.borderWidth = 1
instockTag += 1
print("\(widgetInstockArray.count)")
Cell?.contentView.addSubview(newLabel)
}
}
if i.contains(wTextView) {
print("textView was placed")
newTextView = UITextView(frame: CGRect(x:10, y: 10, width: 200, height: 60))
newTextView.textAlignment = NSTextAlignment.justified
newTextView.textColor = UIColor.black
newTextView.backgroundColor = UIColor.white
newTextView.font = UIFont.systemFont(ofSize: 15)
newTextView.tag = instockTag
print("You have a instock textView with tag \(newTextView.tag)")
if labelInstockArray.isEmpty || idInstockArray.count != labelInstockArray.count {
} else {
//newTextView.text = labelInstockArray[indexPath.row]
newTextView.layer.cornerRadius = 3
newTextView.layer.borderColor = UIColor.gray.cgColor
newTextView.layer.borderWidth = 1
instockTag += 1
print("\(widgetInstockArray.count)")
Cell?.contentView.addSubview(newTextView)
}
}
}
print("could not add widgets")
}
return Cell!
}
func textViewDidBeginEditing(_ textView: UITextView) {
if newTextView.textColor == UIColor.lightGray {
newTextView.text = nil
newTextView.textColor = UIColor.black
}
}
func textViewDidEndEditing(_ textView: UITextView) {
if newTextView.text.isEmpty {
for i in labelInstockArray {
newTextView.text = i
}
newTextView.textColor = UIColor.lightGray
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
输出重叠:(
textFiled在textview中,都出现在单个单元格中。
但是我希望它们不应该重叠,每个单元格中应该只有一个小部件。
如果我想在点击按钮上添加小部件,那么每次点击都应该添加小部件。
这就是我所做的
var idWidgetIs = IntegerLiteralType()
var labelWidget = String()
var widgetName = String()
let stockArray: [StockItem] = [ StockItem(id: idWidgetIs, label: labelWidget, widget: widgetName)]
@IBAction func textViewAct(_ sender: Any) {
idWidgetIs += 1
labelWidget = "placeholder"
StockItem.init(id: idWidgetIs, label: labelWidget, widget: .textView)
}
@IBAction func textFieldAct(_ sender: Any) {
idWidgetIs += 1
labelWidget = "placeholder"
StockItem.init(id: idWidgetIs, label: labelWidget, widget: .textField)
}
答案 0 :(得分:4)
1)您正在以编程方式添加子视图。因为单元格被重用,所以每次都要创建TextField和TextView
2)我在代码中看到的另一个问题是i.contains(wTextField)
由于i.contains(wTextView)
和wTextField
都在数组wTextView
中且两个框架都是widgetInstockArray
,所以CGRect(x: 10, y: 10, width: 200, height: 30)
始终为真,因此您将重叠< / strong>
UIStackView
使用UIStackview
现在向UITextField
添加一个UITextView
和一个UIStackview
。
现在,下一步是cellForRow
方法。只需隐藏其他元素,如
if i == wTextField {
cell.wTextView.isHidden = true
cell.wTextField.isHidden = false
} else {
cell.wTextField.isHidden = true
cell.wTextView.isHidden = false
}
当您隐藏其中一个视图UIStackView
时,其他元素会自动相应地设置
希望它有用,请在查询的情况下告诉我
<强>更新强>
不相关但是保留两个数组以填充tableview不是一个好习惯,这可能会对将来的更新代码造成问题。
更好的解决方案是创建struct
或class
喜欢
enum Widget {
case TextField
case TextView
}
struct StockArray {
var type : Widget
var labelInstockArray = [String]()
var idInstockArray = [IntegerLiteralType]()
}
现在您可以创建StockArray
数组,并且很容易维护
答案 1 :(得分:2)
如this answer中所述:
可以按照以下方式重新构建和改进问题中的示例代码,以获得所需的结果。
定义两种类型,以便更方便地访问单个库存项目的ID,标签和小部件。
enum StockWidget: String {
case textField
case textView
}
struct StockItem {
let id: IntegerLiteralType
let label: String
let widget: StockWidget
}
相应地更新样本数据。
let stockArray: [StockItem] = [
StockItem(id: 1, label: "1ok", widget: .textView),
StockItem(id: 2, label: "2ok", widget: .textField),
StockItem(id: 3, label: "3ok", widget: .textView),
StockItem(id: 4, label: "4ok", widget: .textField),
StockItem(id: 5, label: "5ok", widget: .textField),
StockItem(id: 6, label: "6ok", widget: .textView),
StockItem(id: 7, label: "7ok", widget: .textField)
]
一个人UITextField
:
class TextFieldWidgetCell: UITableViewCell {
let textField: UITextField
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
let field = UITextField(frame: CGRect(x: 10, y: 10, width: 200, height: 30))
field.layer.borderColor = UIColor.gray.cgColor
field.layer.borderWidth = 1.0
field.layer.cornerRadius = 3.0
field.textColor = UIColor.gray
textField = field
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(textField)
}
override func prepareForReuse() {
super.prepareForReuse()
textField.placeholder = nil
textField.text = nil
}
}
和一个UITextView
:
class TextViewWidgetCell: UITableViewCell {
let textView: UITextView
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
let view = UITextView(frame: CGRect(x:10, y: 10, width: 200, height: 60))
view.backgroundColor = UIColor.white
view.font = UIFont.systemFont(ofSize: 15)
view.layer.borderColor = UIColor.gray.cgColor
view.layer.borderWidth = 1.0
view.layer.cornerRadius = 3.0
view.textAlignment = NSTextAlignment.justified
view.textColor = UIColor.black
textView = view
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(textView)
}
override func prepareForReuse() {
super.prepareForReuse()
textView.text = nil
}
}
使用表格视图注册窗口小部件单元格。
override func viewDidLoad() {
super.viewDidLoad()
firstTableView.dataSource = self
firstTableView.delegate = self
firstTableView.register(TextFieldWidgetCell.self, forCellReuseIdentifier: StockWidget.textField.rawValue)
firstTableView.register(TextViewWidgetCell.self, forCellReuseIdentifier: StockWidget.textView.rawValue)
}
UITableViewDataSource
实施既然单元格配置被拆分为两个UITableViewCell
子类,tableView(_, cellForRowAt:)
的实现可以大大减少。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return stockArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let stockItem = stockArray[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: stockItem.widget.rawValue)
switch stockItem.widget {
case .textField:
if let cell = cell as TextFieldWidgetCell {
cell.textField.placeholder = stockItem.label
}
case .textView:
if let cell = cell as TextViewWidgetCell {
cell.textView.text = stockItem.label
}
}
return cell
}
答案 2 :(得分:1)
如果我理解您的代码/需要正确,添加子视图是重叠的不问题。 多次添加子视图是问题
for i in widgetInstockArray {
方法中的 cellForRowAt
行是问题所在。基本上对于每个单元格,您循环遍历(7 times = 3 for wTextView and 4 for wTextField)
,这意味着您要在视图上添加视图。
建议:删除for i in widgetInstockArray {
和
let i = widgetInstockArray[indexPath.row]
并使用
进行比较 if i == wTextField {
和wTextView类似。