wake-up-neo.net

Benutzerdefinierte UITableViewCell von der Feder in Swift

Ich versuche, eine benutzerdefinierte Tabellenzellenzelle aus einer Spitze zu erstellen. Ich beziehe mich auf diesen Artikel hier . Ich habe zwei Probleme.

Ich habe eine .xib-Datei erstellt, auf die ein UITableViewCell-Objekt gezogen wurde. Ich habe eine Unterklasse von UITableViewCell erstellt und als Klasse der Zelle und Cell als wiederverwendbaren Bezeichner festgelegt.

import UIKit

class CustomOneCell: UITableViewCell {

    @IBOutlet weak var middleLabel: UILabel!
    @IBOutlet weak var leftLabel: UILabel!
    @IBOutlet weak var rightLabel: UILabel!

    required init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

Im UITableViewController habe ich diesen Code,

import UIKit

class ViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {

    var items = ["Item 1", "Item2", "Item3", "Item4"]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // MARK: - UITableViewDataSource
    override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
        let identifier = "Cell"
        var cell: CustomOneCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomOneCell
        if cell == nil {
            tableView.registerNib(UINib(nibName: "CustomCellOne", bundle: nil), forCellReuseIdentifier: identifier)
            cell = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomOneCell
        }

        return cell
    }
}

Dieser Code entspricht keinen Fehlern, aber wenn ich ihn im Simulator starte, sieht es so aus.

enter image description here

Im UITableViewController im Storyboard habe ich nichts mit der Zelle gemacht. Leerer Bezeichner und keine Unterklasse. Ich habe versucht, die Cell - Kennung zur Prototypzelle hinzuzufügen und sie erneut auszuführen, aber ich erhalte das gleiche Ergebnis.

Ein anderer Fehler war, als ich versuchte, die folgende Methode im UITableViewController zu implementieren.

override func tableView(tableView: UITableView!, willDisplayCell cell: CustomOneCell!, forRowAtIndexPath indexPath: NSIndexPath!) {

    cell.middleLabel.text = items[indexPath.row]
    cell.leftLabel.text = items[indexPath.row]
    cell.rightLabel.text = items[indexPath.row]
}

Wie in dem Artikel gezeigt, den ich erwähnt habe, änderte ich die Typform cell des Parameters UITableViewCell in CustomOneCell, die meine Unterklasse von UITableViewCell ist. Aber ich erhalte den folgenden Fehler,

Überschreibungsmethode mit dem Selektor 'tableView: willDisplayCell: forRowAtIndexPath:' hat inkompatiblen Typ '(UITableView !, CustomOneCell!, NSIndexPath!) -> ()'

Hat jemand eine Idee, wie man diese Fehler beheben kann? Dies schien in Objective-C gut zu funktionieren.

Vielen Dank.

BEARBEITEN: Ich habe gerade bemerkt, dass ich, wenn ich die Ausrichtung des Simulators in Querformat ändere und ihn wieder in Hochformat umwandle, die Zellen erscheinen! Ich konnte immer noch nicht herausfinden, was los ist. Ich habe ein Xcode-Projekt here hochgeladen, das das Problem veranschaulicht, wenn Sie Zeit für einen kurzen Blick haben.

114
Isuru

Sie sollten den folgenden Code für Ihr Projekt ausprobieren: (Syntax für Swift 3+)

CustomOneCell.Swift

import UIKit

class CustomOneCell: UITableViewCell {

    // Link those IBOutlets with the UILabels in your .XIB file
    @IBOutlet weak var middleLabel: UILabel!
    @IBOutlet weak var leftLabel: UILabel!
    @IBOutlet weak var rightLabel: UILabel!

}

TableViewController.Swift

import UIKit

class TableViewController: UITableViewController {

    let items = ["Item 1", "Item2", "Item3", "Item4"]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UINib(nibName: "CustomOneCell", bundle: nil), forCellReuseIdentifier: "CustomCellOne")    
    }

    // MARK: - UITableViewDataSource

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

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("CustomCellOne", forIndexPath: indexPath) as! CustomOneCell

        cell.middleLabel.text = items[indexPath.row]
        cell.leftLabel.text = items[indexPath.row]
        cell.rightLabel.text = items[indexPath.row]

        return cell
    }
}

Das Bild unten zeigt eine Reihe von Einschränkungen, die mit dem bereitgestellten Code funktionieren, ohne dass eine Mehrdeutigkeitsbeschränkung von Xcode vorliegt.

 enter image description here

173
Imanou Petit

Hier ist mein Ansatz mit Swift 2 und Xcode 7.3. In diesem Beispiel wird ein einzelner ViewController verwendet, um zwei .xib-Dateien zu laden - eine für eine UITableView und eine für die UITableCellView.

 enter image description here

In diesem Beispiel können Sie eine UITableView direkt in eine leere TableNib .xib-Datei einfügen. Setzen Sie den Besitzer der Datei file auf Ihre ViewController-Klasse und verwenden Sie einen Ausgang, um auf die tableView zu verweisen.

 enter image description here

und

 enter image description here

Jetzt können Sie in Ihrem View-Controller die tableView wie gewohnt delegieren

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    ...

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // Table view delegate
        self.tableView.delegate = self
        self.tableView.dataSource = self

        ...

Zum Erstellen Ihrer benutzerdefinierten Zelle legen Sie erneut ein Table-View-Zellenobjekt in einer leeren TableCellNib .xib-Datei ab. Diesmal müssen Sie in der Zelle .xib-Datei keinen "Besitzer" angeben, aber Sie müssen eine benutzerdefinierte Klasse und einen Identifier wie "TableCellId" angeben

 enter image description here  enter image description here

Erstellen Sie Ihre Unterklasse mit den gewünschten Auslässen

class TableCell: UITableViewCell {

    @IBOutlet weak var nameLabel: UILabel!

}

Zum Schluss ... zurück in Ihrem View Controller können Sie das Ganze laden und anzeigen

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    // First load table nib
    let bundle = NSBundle(forClass: self.dynamicType)
    let tableNib = UINib(nibName: "TableNib", bundle: bundle)
    let tableNibView = tableNib.instantiateWithOwner(self, options: nil)[0] as! UIView

    // Then delegate the TableView
    self.tableView.delegate = self
    self.tableView.dataSource = self

    // Set resizable table bounds
    self.tableView.frame = self.view.bounds
    self.tableView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

    // Register table cell class from nib
    let cellNib = UINib(nibName: "TableCellNib", bundle: bundle)
    self.tableView.registerNib(cellNib, forCellReuseIdentifier: self.tableCellId)

    // Display table with custom cells
    self.view.addSubview(tableNibView)

}

Der Code zeigt, wie Sie einfach eine Nib-Datei (die Tabelle) laden und anzeigen können, und zweitens, wie Sie eine Nib für die Zellnutzung registrieren. 

Hoffe das hilft!!!

26
internet-nico

Schnell 4

Register Nib

tblMissions.register(UINib(nibName: "MissionCell", bundle: nil), forCellReuseIdentifier: "MissionCell")

In der TableView-Datenquelle 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          guard let cell = tableView.dequeueReusableCell(withIdentifier: "MissionCell", for: indexPath) as? MissionCell else { return UITableViewCell() }
          return cell
    }
11
GSK

Eine andere Methode, die für Sie funktionieren kann (so mache ich es), ist das Registrieren einer Klasse.

Angenommen, Sie erstellen eine benutzerdefinierte TableView wie folgt:

class UICustomTableViewCell: UITableViewCell {...}

Sie können diese Zelle dann in dem UITableViewController registrieren, in dem Sie sie mit "registerClass" anzeigen möchten:

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.registerClass(UICustomTableViewCell.self, forCellReuseIdentifier: "UICustomTableViewCellIdentifier")
}

Und Sie können es so aufrufen, wie Sie es in der Zelle für Zeilenmethode erwarten würden:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("UICustomTableViewCellIdentifier", forIndexPath: indexPath) as! UICustomTableViewCell
    return cell
}
3
Ethan Kay

Zum Beheben der "Überschreibungsmethode ... hat nicht kompatiblen Typ ..." error Ich habe die Funktionsdeklaration in geändert

override func tableView(tableView: (UITableView!), 
                        cellForRowAtIndexPath indexPath: (NSIndexPath!)) 
    -> UITableViewCell {...}

(war -> UITableViewCell! - mit Ausrufezeichen am Ende)

2
tse

Sie haben Ihre Feder nicht wie folgt registriert:

tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
2
vsujan

Schnell 4.1.2

xib. 

Erstellen Sie ImageCell2.Swift

Schritt 1

import UIKit

class ImageCell2: UITableViewCell {

    @IBOutlet weak var imgBookLogo: UIImageView!
    @IBOutlet weak var lblTitle: UILabel!
    @IBOutlet weak var lblPublisher: UILabel!
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

}

schritt 2 . Entsprechend Viewcontroller-Klasse

  import UIKit

    class ImageListVC: UIViewController,UITableViewDataSource,UITableViewDelegate {
    @IBOutlet weak var tblMainVC: UITableView!

    var arrBook : [BookItem] = [BookItem]()

    override func viewDidLoad() {
        super.viewDidLoad()
         //Regester Cell
        self.tblMainVC.register(UINib.init(nibName: "ImageCell2", bundle: nil), forCellReuseIdentifier: "ImageCell2")
        // Response Call adn Disply Record
        APIManagerData._APIManagerInstance.getAPIBook { (itemInstance) in
            self.arrBook = itemInstance.arrItem!
            self.tblMainVC.reloadData()
        }
    }
    //MARK: DataSource & delegate
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.arrBook.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//    [enter image description here][2]
        let cell  = tableView.dequeueReusableCell(withIdentifier: "ImageCell2") as! ImageCell2
        cell.lblTitle.text = self.arrBook[indexPath.row].title
        cell.lblPublisher.text = self.arrBook[indexPath.row].publisher
        if let authors = self.arrBook[indexPath.row].author {
            for item in authors{
                print(" item \(item)")
            }
        }
        let  url  = self.arrBook[indexPath.row].imageURL
        if url == nil {
            cell.imgBookLogo.kf.setImage(with: URL.init(string: ""), placeholder: UIImage.init(named: "download.jpeg"))
        }
        else{
            cell.imgBookLogo.kf.setImage(with: URL(string: url!)!, placeholder: UIImage.init(named: "download.jpeg"))
        }
        return cell
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 90
    } 

}
1
user3263340

Nehmen Sie einfach ein Xib mit der Klasse UITableViewCell. Legen Sie die Benutzeroberfläche wie erforderlich fest, und weisen Sie IBOutlet zu. Verwenden Sie es in cellForRowAt () der Tabellenansicht wie folgt:

//MARK: - table method

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.arrayFruit.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell:simpleTableViewCell? = tableView.dequeueReusableCell(withIdentifier:"simpleTableViewCell") as? simpleTableViewCell
    if cell == nil{
        tableView.register(UINib.init(nibName: "simpleTableViewCell", bundle: nil), forCellReuseIdentifier: "simpleTableViewCell")
        let arrNib:Array = Bundle.main.loadNibNamed("simpleTableViewCell",owner: self, options: nil)!
        cell = arrNib.first as? simpleTableViewCell
    }

    cell?.labelName.text = self.arrayFruit[indexPath.row]
    cell?.imageViewFruit.image = UIImage (named: "fruit_img")

    return cell!

}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
 return 100.0
}

 enter image description here

100% arbeitslos (getestet)

0