Am'm încercarea de a crea un tabel de celule dintr-o peniță. Am'm referindu-se la acest articol aici. Am'm confruntă cu două probleme.
Am creat-o .fișier xib cu un UITableViewCell obiect târât pe la ea. Am creat o subclasă de UITableViewCell
și setați-o ca celula's class și Mobil ca reutilizabile de identificare.
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
}
}
În UITableViewController am acest cod,
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
}
}
Acest cod este în conformitate cu erori, dar atunci când am rula în simulator, se pare ca acest lucru.
În UITableViewController în rezumat nu am't face nimic pentru a celulei. Gol de identificare și nu subclasă. Am încercat adăugarea Mobil identificator prototip mobil și a fugit din nou, dar am obține același rezultat.
Un alt eroare m-am confruntat este, atunci când am încercat să pună în aplicare următoarele metode în UITableViewController.
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]
}
Așa cum se arată în articolul menționat am schimbat "celula" parametru's de tip form UITableViewCell " la " CustomOneCell
care mi-e subclasă de UITableViewCell. Dar primesc urmatoarea eroare,
Metodă de înlocuire cu selector 'tableView:willDisplayCell:forRowAtIndexPath:' are incompatibile tip '(UITableView!, CustomOneCell!, NSIndexPath!) -> ()'
Oricine are nici o idee cum să rezolve aceste erori? Aceste părea să funcționeze bine în Objective-C.
Multumesc.
EDIT: tocmai am observat ca daca am schimba simulator's orientarea la peisaj și rotiți-l înapoi la portret, celulele apar! Eu încă n't mi dau seama ce's întâmplă. Am încărcat un proiect Xcode aici demonstrează o problemă dacă aveți timp pentru o privire rapidă.
Cu Swift 5 și iOS 12.2, ar trebui să încercați următorul cod pentru a rezolva problema:
CustomCell.swift
import UIKit
class CustomCell: 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: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
}
// MARK: - UITableViewDataSource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
cell.middleLabel.text = items[indexPath.row]
cell.leftLabel.text = items[indexPath.row]
cell.rightLabel.text = items[indexPath.row]
return cell
}
}
Imaginea de mai jos prezinta un set de constrângeri care lucrează cu codul furnizat fără constrângeri ambiguitate mesaj de Xcode:
Aici's my abordare folosind Swift 2 și Xcode 7.3. Acest exemplu va folosi un singur ViewController de a încărca două .fișiere xib-unul pentru un UITableView și unul pentru UITableCellView.
Pentru acest exemplu, puteți arunca o UITableView chiar într-un gol TableNib.fișier xib. În interior, setați file's proprietar la ViewController de clasă și de a folosi o priză de referință tableView.
și
Acum, în opinia dumneavoastră, controler, puteți delega tableView în mod normal ar fi, ca
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
...
Pentru a crea Personalizate de celule, din nou, arunca un Tabel de Celule obiect într-un gol TableCellNib.fișier xib. De această dată, în celulă .fișier xib nu't trebuie să specificați un "proprietar" dar ai nevoie pentru a specifica un Clasa Personalizat si un identificare ca "TableCellId"
Creați-vă subclasă cu orice puncte de care aveți nevoie ca atât
class TableCell: UITableViewCell {
@IBOutlet weak var nameLabel: UILabel!
}
În cele din urmă înapoi în Vedere Controler, puteți încărca și afișa întregul lucru atât de
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)
}
Codul arată cum puteți pur și simplu încărcați și afișa o peniță de fișier (tabel), iar al doilea cum de a înregistra o peniță pentru mobil utilizat.
Sper că acest lucru vă ajută!!!
Swift 4
Registrul Peniță
tblMissions.register(UINib(nibName: "MissionCell", bundle: nil), forCellReuseIdentifier: "MissionCell")
În TableView Sursă De Date
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MissionCell", for: indexPath) as? MissionCell else { return UITableViewCell() }
return cell
}
O altă metodă care ar putea lucra pentru tine (it's cum o fac) se înregistrează o clasă.
Presupunem că creați un custom tableView, cum ar fi următoarele:
class UICustomTableViewCell: UITableViewCell {...}
Apoi, puteți înregistra această celulă în orice UITableViewController va afișa în cu "registerClass":
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(UICustomTableViewCell.self, forCellReuseIdentifier: "UICustomTableViewCellIdentifier")
}
Si puteti spune ca v-ar aștepta în celula de rând metoda:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("UICustomTableViewCellIdentifier", forIndexPath: indexPath) as! UICustomTableViewCell
return cell
}
Soluție detaliată cu Capturi de ecran
UITableViewCell
ca rădăcină de fișier xib și orice alte componente vizuale vrei.MyCustomCell
ca o subclasă de UITableViewCell
.`` clasa MyViewController: UIViewController {
@IBOutlet slab var myTable: UITableView!
prototipul func {viewDidLoad super.viewDidLoad()
să nib = UINib(nibName: "MyCustomCell", pachet: zero) myTable.înregistrați(peniță, forCellReuseIdentifier: "MyCustomCell") myTable.dataSource = auto }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { dacă să celula = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell") cum? MyCustomCell { mobil.myLabel.text = "Hello world." reveni celulă } ... } }
``
Pentru a remedia "metodă de înlocuire a incompatibilă tip..." eroare de am'am schimbat declarația funcției de
override func tableView(tableView: (UITableView!),
cellForRowAtIndexPath indexPath: (NSIndexPath!))
-> UITableViewCell {...}
(s -> UITableViewCell!
- cu semnul exclamării la final)
swift 4.1.2
xib.
Crea ImageCell2.swift
Pasul 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)
}
}
pasul 2 . Conform Viewcontroller clasa
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
}
}
Am avut de a face sigur că, atunci când crearea de evacuare pentru a specifica faptul că am fost prindere la celula, nu obiectul's proprietarului. Când apare meniul de la nume trebuie să selectați-l din 'obiect' meniu vertical. Desigur, trebuie să declare celulă ca clasa ta, nu doar 'TableViewCellClass'. Altfel mi-ar ține obtinerea clasa nu cheie conforme.
Simplu să ia o xib cu clasa UITableViewCell. Setați UI ca pe reuirement și atribui IBOutlet. Folositi-l în cellForRowAt() din tabel astfel:
//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
}
100% de lucru fără nici o problemă (Testat)