文本重叠应该删除的文本

Text Overlapping Text That Should've deleted

HI, so this is my vc for a view where I save info about a plane (the type and rego). It saves the plane and deletes and you can close the app and come back and it saves it there in the core data model but I have a weird problem. After you make a plane and it shows in the table view and add a few more planes (table view cell which has info) then the labels which display the info start to overlap with what should be deleted information. The pictures bellow show what I mean. Any help would be greatly appreciated.

var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

var typeField: UITextField?
var regoField: UITextField?

@IBAction func addPlaneButton(_ sender: Any) {

   let alertController = UIAlertController(title: "New Plane", message: "Please Input The Type And Registration", preferredStyle: .alert)
    alertController.addTextField(configurationHandler: typeField)
    alertController.addTextField(configurationHandler: regoField)

    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
    let saveAction = UIAlertAction(title: "Save", style: .default, handler: self.savePlane)

    alertController.addAction(cancelAction)
    alertController.addAction(saveAction)

    self.present(alertController, animated: true)


    print("Add Plane Pressed")
}

func typeField(textField: UITextField!) {
    typeField = textField
    typeField?.placeholder = "Aircraft Type"
}

func regoField(textField: UITextField!) {
    regoField = textField
    regoField?.placeholder = "Aircraft Registration"
}



@IBOutlet weak var tableView: UITableView!

var timer = Timer()

let utcItem = UIBarButtonItem()
let utcLbl = UILabel()


override func viewDidLoad() {
    super.viewDidLoad()

    //Table View
    tableView.delegate = self
    tableView.dataSource = self
    self.tableView.rowHeight = 88

    setupView()

}


            //////Functions////


func setupView() {
    //UTC Time Formatter
    let dateFormatter = DateFormatter()
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    dateFormatter.dateFormat = "HH:mm"
    _ = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)

    //UTC Time
    utcLbl.frame = CGRect(x: 0, y: 0, width: 100, height: 20)
    utcLbl.text = "\(dateFormatter.string(from: Date())) UTC"
    utcItem.customView = utcLbl
    utcLbl.backgroundColor = UIColor.init(fromHexCode: "4FB7F1")
    utcLbl.layer.cornerRadius = 10
    utcLbl.textAlignment = .center
    utcLbl.layer.masksToBounds = true // Or utcLbl.clipsToBounds = true
    self.navigationItem.setLeftBarButtonItems([utcItem], animated: true)

    // Large Title
    self.title = "Planes"
    self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.font: UIFont(name: "Avenir-Black", size: 35)!]
    self.navigationController?.navigationBar.prefersLargeTitles = true
    let customBlue = UIColor(red:0.08, green:0.38, blue:0.75, alpha:1.0)
    navigationController?.navigationBar.barTintColor = customBlue
}

//Constant UTC Time Lbl
@objc func updateTime() {
    let formatter = DateFormatter()
    formatter.timeZone = TimeZone(abbreviation: "UTC")
    formatter.dateFormat = "HH:mm"
    utcLbl.text = formatter.string(from: Date()) + " UTC"
}

//Save the Plane Info

func savePlane(alert: UIAlertAction) {

    if typeField?.text != "" || regoField?.text != "" {

        let newLog = NSEntityDescription.insertNewObject(forEntityName: "Planes", into: context)
        newLog.setValue(self.typeField?.text, forKey: "type")
        newLog.setValue(self.regoField?.text, forKey: "rego")

        do{
            try context.save()
        }
        catch {
            print(error)
        }

        //Making the table update itself when user logs the plane
        self.fetchData()
        self.tableView.reloadData()

    }
    print("Plane Saved")
}

func fetchData() {
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext


    do{
        planeArray = try context.fetch(Planes.fetchRequest())
    }
    catch{
        print(error)
    }
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    if editingStyle == .delete {
        let save = planeArray[indexPath.row]
        context.delete(save)
        (UIApplication.shared.delegate as! AppDelegate).saveContext()

        do {
            planeArray = try context.fetch(Planes.fetchRequest())
        }
        catch {
            print(error)
        }
        tableView.reloadData()
    }
}


//Table View Functions

public func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return (planeArray.count)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    //Plane Pic
    let planeView = UIImageView()
    planeView.frame = CGRect(x: 0, y: 0, width: 69, height: 67)
    //planeView.center = CGPoint(x: cell.center.x - 150, y: cell.center.y)
    planeView.center = CGPoint(x: cell.center.x - 145, y: cell.center.y)
    let planeImage: UIImage = UIImage(named: "plane")!
    planeView.image = planeImage
    cell.addSubview(planeView)

    //Type Label
    let type = UILabel()
    type.frame = CGRect(x: 0, y: 0, width: 45, height: 21)
    type.center = CGPoint(x: cell.center.x - 80, y: cell.center.y - 22.5)
    type.text = "Type:"
    type.font = UIFont(name: "Montserrat-Medium", size: 17)
    cell.addSubview(type)

    //Type Answer
    let typeAnswer = UILabel()
    typeAnswer.frame = CGRect(x: 0, y: 0, width: 220, height: 21)
    typeAnswer.center = CGPoint(x: cell.center.x + 62.5, y: cell.center.y - 22.5)
    typeAnswer.text = ""
    typeAnswer.font = UIFont(name: "Montserrat-Light", size: 17)
    typeAnswer.textAlignment = .right
    cell.addSubview(typeAnswer)

    //Rego Label
    let rego = UILabel()
    rego.frame = CGRect(x: 0, y: 0, width: 110, height: 21)
    rego.center = CGPoint(x: cell.center.x - 47.5, y: cell.center.y + 18.5)
    rego.text = "Registration:"
    rego.font = UIFont(name: "Montserrat-Medium", size: 17)
    cell.addSubview(rego)

    //rego answer
    let regoAnswer = UILabel()
    regoAnswer.frame = CGRect(x: 0, y: 0, width: 160, height: 21)
    regoAnswer.center = CGPoint(x: cell.center.x + 92.5, y: cell.center.y + 18.5)
    regoAnswer.text = ""
    regoAnswer.font = UIFont(name: "Montserrat-Light", size: 17)
    regoAnswer.textAlignment = .right
    cell.addSubview(regoAnswer)

    let save = planeArray[indexPath.row]
    typeAnswer.text = save.type
    regoAnswer.text = save.rego
    return cell
}


override func viewWillAppear(_ animated: Bool) {
    //Making the table update itself when user logs the plane
    fetchData()
    tableView.reloadData()
}

}

UITableView 重复使用单元格。在你的例子中,当第一次创建单元格时,你向它添加一个 UILabel 。下次加载此单元格时,UITableView 会重新使用现有单元格,并且 cellForRowAt 会向此单元格添加另一个 UILabel。正确的实现是创建自定义 UITableViewCell 并重置 cellForRowAt 方法中所有属性的值。

您可以尝试下面的操作(请注意,这只是一个粗略的实现,假设您了解 ios 编程的基础知识。如果不是这样,我建议您研究一下有点):

添加自定义表格视图单元格

class CustomTableViewCell: UITableViewCell {
    @IBOutlet weak var imgViewPlane: UIImageView!
    @IBOutlet weak var lblType: UILabel!
    @IBOutlet weak var lblTypeAnswer: UILabel!
    @IBOutlet weak var lblRego: UILabel!
    @IBOutlet weak var lblRegoAnswer: UILabel!
}

在情节提要表视图和 link IBOutlet 中创建一个动态原型单元格。然后在你的cellForRowAt中,做这样的事情

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomTableViewCell

    cell.imgViewPlane.image = planeImage
    cell.lblType.text = "Type:"
    cell.lblTypeAnswer.text = planeArray[indexPath.row].type
    cell.lblRego.text = "Registration:"
    cell.lblRegoAnswer.text = planeArray[indexPath.row].rego

    return cell
}

每次单元格出列时,您都在向单元格添加新的子视图。


我建议您将这些视图、标签等创建为 UITableViewCell 子类中的 lazy 变量,并将它们添加为 awakeFromNib()

中的子视图
class YourCell: UITableViewCell {

    lazy var label: UILabel = {
        var label = UILabel(...)
        ...
        return label
    }()
    ...
    override func awakeFromNib() {
        addSubview(label)
        ...
    }
}

..... 或者如果你使用的是故事板

,则使用IBOutlet

然后在 cellForRowAt 中只需更改向下转换单元子类的视图的属性

let cell = ... as! YourCell
cell.label.text = ""
cell.anotherLabel.isHidden = true
...