我有两个部分的自动调整单元格的tableview:成分和步骤。当我交替添加细胞并且我选择在成分部分添加第6个细胞时,步骤部分标题被复制并且新的成分细胞被添加到新的步骤标题下面。显然,这不是我想要的。我检查了我的索引路径和数据源,看起来数据进入了正确的位置,所以我不确定问题的根源是什么。我在这个GitHub项目中创建了一个行为示例:https://github.com/amos-nistrian/dynamic-textView。
MainViewController.swift
import UIKit
protocol ButtonCellDelegate: class {
func shouldAddCellInSection(section: Int)
}
protocol ExpandingCellDelegate: class {
func updateCellHeight(_ indexPath: IndexPath, comment: String)
func updateArray(_ indexPath: IndexPath, text: String)
}
class MainViewController: UITableViewController, ExpandingCellDelegate, ButtonCellDelegate {
var steps = [String]()
var ingredients = [String]()
let redColor = UIColor(red:0.93, green:0.12, blue:0.14, alpha:1.0)
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.separatorStyle = .none // remove lines between cells
self.tableView.allowsSelection = false // remove highlighting when selecting a cell
}
//////* tableview delegate stuff below here *///////////////////////////////////////////////////////////////////////////////
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
var headers : [String] = ["Ingredients", "Steps"]
return headers[section]
}
override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
if let header = view as? UITableViewHeaderFooterView {
header.textLabel?.textColor = UIColor.black
header.backgroundView?.backgroundColor = UIColor.red.withAlphaComponent(0.35)
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch(section) {
case 0:
return ingredients.count + 1 // plus one for the button
case 1 :
return steps.count + 1 // plus one for the button
default:
return 0;
}
}
// To enable self-sizing table view cells
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
// To enable self-sizing table view cells
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let section = indexPath.section
let row = indexPath.row
switch (section) {
case 0:
if (row == 0) {
let cell = tableView.dequeueReusableCell(withIdentifier: "Button Cell", for: indexPath) as! ButtonCell
cell.delegate = self as ButtonCellDelegate
cell.button.setTitle("+ Ingredient ", for: .normal)
cell.btnInSection = section
cell.button.tag = 0
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "Picker Text View Cell", for: indexPath) as! PickerTextViewCell
cell.delegate = self as ExpandingCellDelegate
cell.cellIndexPath = indexPath
print("index path is ",indexPath)
print(cell.textView)
cell.textView.text = ingredients[row-1]
return cell
}
case 1:
if (row == 0) {
let cell = tableView.dequeueReusableCell(withIdentifier: "Button Cell", for: indexPath) as! ButtonCell
cell.delegate = self as ButtonCellDelegate
cell.button.setTitle("+ Step ", for: .normal)
cell.btnInSection = section
cell.button.tag = 1
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "Text View Cell", for: indexPath) as! TextViewCell
cell.textView.text = steps[row-1]
cell.cellIndexPath = indexPath
cell.delegate = self as ExpandingCellDelegate
//cell.delegate = self
return cell
}
default:
let cell = tableView.dequeueReusableCell(withIdentifier: "Text View Cell", for: indexPath) as! TextViewCell
return cell
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Adds a new cell to the table and data source
func shouldAddCellInSection(section: Int) {
// Update the data source
if (section == 0) {
ingredients.append("")
} else {
steps.append("")
}
let row = tableView.numberOfRows(inSection: section)
print(row)
print(section)
UIView.setAnimationsEnabled(false)
let indexPath = IndexPath(row: row, section: section)
tableView.beginUpdates()
self.tableView.insertRows(at: [indexPath], with: .none)
tableView.endUpdates()
UIView.setAnimationsEnabled(true)
tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.top, animated: true)
}
// MARK: ExpandingCellDelegate
// update the table view cell height
func updateCellHeight(_ indexPath: IndexPath, comment: String) {
UIView.setAnimationsEnabled(false)
self.tableView.beginUpdates()
self.tableView.setNeedsDisplay()
self.tableView.endUpdates()
self.tableView.scrollToRow(at: indexPath, at: .top, animated: false)
UIView.setAnimationsEnabled(true)
}
// update the data source on key press
func updateArray(_ indexPath: IndexPath, text: String) {
let row = indexPath.row-1
let section = indexPath.section
if (section == 0) {
print("Appedning [", text , "] to ingredients[",row,"]")
self.ingredients[row] = text
} else {
self.steps[row] = text
}
}
} //EOC
PickerTextViewCell
import UIKit
class PickerTextViewCell: UITableViewCell, UITextViewDelegate {
let greyTextColor = UIColor(red:0.47, green:0.47, blue:0.44, alpha:1.0)
let lightGreyBackgroundColor = UIColor(red:0.93, green:0.93, blue:0.93, alpha:1.0)
let darkerGreyBackgroundColor = UIColor(red:0.77, green:0.77, blue:0.77, alpha:1.0)
var delegate: ExpandingCellDelegate!
var cellIndexPath: IndexPath!
@IBOutlet weak var textHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var textView: UITextView! {
didSet {
textView.backgroundColor = darkerGreyBackgroundColor
textView.textColor = greyTextColor
textView.layer.cornerRadius = 5
}
}
override func awakeFromNib() {
super.awakeFromNib()
self.textView.delegate = self
}
// hide the keyboard when the user presses done on the keyboard
// also resizes the textview
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
//print("Content Height \(self.textView.contentSize.height) ")
//print("Constraint is", self.textHeightConstraint.constant )
if(self.textView.contentSize.height < self.textHeightConstraint.constant) {
self.textView.isScrollEnabled = false
} else {
self.textView.isScrollEnabled = true
}
if (text == "\n") {
textView.resignFirstResponder()
return false
}
self.delegate.updateArray(self.cellIndexPath, text: textView.text)
self.delegate.updateCellHeight(self.cellIndexPath, comment: textView.text)
return true
}
func textViewDidBeginEditing(_ textView: UITextView) {
textView.backgroundColor = UIColor.cyan
textView.textColor = UIColor.black
}
// hide the keyboard if the user taps somewhere else
func textViewDidEndEditing(_ textView: UITextView) {
textView.backgroundColor = lightGreyBackgroundColor
textView.textColor = greyTextColor
textView.resignFirstResponder()
self.delegate.updateArray(self.cellIndexPath, text: textView.text)
}
} // EOC
TextViewCell
import UIKit
class TextViewCell: UITableViewCell, UITextViewDelegate {
let greyTextColor = UIColor(red:0.47, green:0.47, blue:0.44, alpha:1.0)
let lightGreyBackgroundColor = UIColor(red:0.93, green:0.93, blue:0.93, alpha:1.0)
let darkerGreyBackgroundColor = UIColor(red:0.77, green:0.77, blue:0.77, alpha:1.0)
var delegate: ExpandingCellDelegate!
var cellIndexPath: IndexPath!
@IBOutlet weak var textHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var label: UILabel! {
didSet {
label.font = UIFont.systemFont(ofSize: 15)
label.textColor = UIColor.lightGray
}
}
@IBOutlet weak var textView: UITextView! {
didSet {
//textView.backgroundColor = darkerGreyBackgroundColor
textView.backgroundColor = UIColor.brown
textView.textColor = greyTextColor
textView.layer.cornerRadius = 5
}
}
override func awakeFromNib() {
super.awakeFromNib()
self.textView.delegate = self
}
// hide the keyboard when the user presses done on the keyboard
// Also resizes the textview
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
print("Content Height \(self.textView.contentSize.height) ")
print("Constraint is", self.textHeightConstraint.constant )
if(self.textView.contentSize.height < self.textHeightConstraint.constant) {
self.textView.isScrollEnabled = false
} else {
self.textView.isScrollEnabled = true
}
if (text == "\n") {
textView.resignFirstResponder()
return false
}
self.delegate.updateArray(self.cellIndexPath, text: textView.text)
self.delegate.updateCellHeight(self.cellIndexPath, comment: textView.text)
return true
}
func textViewDidBeginEditing(_ textView: UITextView) {
textView.backgroundColor = UIColor.cyan
textView.textColor = UIColor.black
}
// hide the keyboard if the user taps somewhere else
func textViewDidEndEditing(_ textView: UITextView) {
textView.backgroundColor = lightGreyBackgroundColor
textView.textColor = greyTextColor
textView.resignFirstResponder()
self.delegate.updateArray(self.cellIndexPath, text: textView.text)
}
} // EOC