This is the custom class for my cell:
class showSugTableViewCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: .Default, reuseIdentifier: "showSug")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
let categoryLbl = UILabel()
categoryLbl.frame = CGRectMake(20, 10, 100, 20)
categoryLbl.text = "Text"
contentView.addSubview(categoryLbl)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
And here's the code from cellForRowAtIndexPath:
let cell = tableView.dequeueReusableCellWithIdentifier("showSug") as! showSugTableViewCell
return cell
The problem is that my app crashes on the cell initialisation, and the log says:
fatal error: unexpectedly found nil while unwrapping an Optional value
How can I solve this?
EDIT:
I changed my code to this:
let cellTemp = self.sugTableView.dequeueReusableCellWithIdentifier("showSug")
var cell = cellTemp as? showSugTableViewCell!
if cell == nil {
self.sugTableView.registerNib(UINib(nibName: "showSugTableViewCell", bundle: nil), forCellReuseIdentifier: "showSug")
self.sugTableView.registerClass(showSugTableViewCell.classForCoder(), forCellReuseIdentifier: "showSug")
cell = showSugTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "showSug")
}
return cell!
However, the app now crashed on the return statement.
Try following case to confirm the issue - I strongly believe following 2 issues might be your problem
if let retCell = tableView.dequeueReusableCellWithIdentifier("showSug") {
if let cell = retCell as? showSugTableViewCell {
//use the cell object
}else {
//1. cell may not be of type showSugTableViewCell so filing t convert
//If it is the case check in identifier you set in nib
}
}else {
//2. tableView.dequeueReusableCellWithIdentifier may not be returning for "showSug"
//Check class type it return table cell
}
Related
I encountered an error during development.
The minimum target is iOS 13.
You want to give different cells for each section using DiffableDataSource.
I don't know why there's an error.
I need your help.
minumum target: iOS 13.0 *
🚨 errorCode 🚨
Thread 1: "unable to dequeue a cell with identifier MuseumItemCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard"
don't used Storyboard, only programming UI
-- ✅ CODE ✅ --
import UIKit
import SnapKit
final class MuseumViewController: UIViewController {
enum Item: Hashable {
case bannerItem([String])
case numberItem([Int])
}
enum MySection: Int {
case banner
case number
}
var tableView = UITableView()
var dataSource: UITableViewDiffableDataSource<MySection, Item>!
var banners: [String] {
[
"ABCDEFGHIJKL",
"ABCDE",
"A",
]
}
var numbers: [Int] = [100000, 10000, 1000, 100, 10, 10]
override func viewDidLoad() {
super.viewDidLoad()
setupTableView()
fetchDataSource()
fetchSnapShot()
}
func setupTableView() {
view.addSubview(tableView)
tableView.register(MuseumBannerCell.self, forCellReuseIdentifier: MuseumBannerCell.identifier)
tableView.register(MuseumNumberCell.self, forCellReuseIdentifier: MuseumNumberCell.identifier)
tableView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
}
func fetchSnapShot() {
var snapshot = NSDiffableDataSourceSnapshot<MySection, Item>()
snapshot.appendSections([.banner, .number])
snapshot.appendItems([.bannerItem(banners), .numberItem(numbers)])
dataSource.apply(snapshot)
}
func fetchDataSource() {
dataSource = UITableViewDiffableDataSource<MySection, Item>(
tableView: tableView
) { tableView, indexPath, itemIdentifier in
let section = MySection(rawValue: indexPath.section)
switch section {
case .banner:
guard let cell = tableView.dequeueReusableCell(
withIdentifier: MuseumBannerCell.id,
for: indexPath
) as? MuseumBannerCell else { return UITableViewCell() }
cell.backgroundColor = .red
return cell
case .number:
guard let cell = tableView.dequeueReusableCell(
withIdentifier: MuseumNumberCell.id,
for: indexPath
) as? MuseumNumberCell else { return UITableViewCell() }
cell.backgroundColor = .blue
return cell
default:
return UITableViewCell()
}
}
}
}
class MuseumBannerCell: UITableViewCell {
static let id: String = "MuseumBannerCell"
// MARK: - Initialize
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MuseumNumberCell: UITableViewCell {
static let id: String = "MuseumItemCell"
// MARK: - Initialize
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
In your setupTableView method you set
tableView.register(MuseumBannerCell.self, forCellReuseIdentifier: MuseumBannerCell.identifier)
tableView.register(MuseumNumberCell.self, forCellReuseIdentifier: MuseumNumberCell.identifier)
and later you call
tableView.dequeueReusableCell(withIdentifier: MuseumBannerCell.id, for: indexPath)
Try to register the cells with MuseumBannerCell.id (and MuseumNumberCell.id) since that's the same identifier you use for dequeuing.
tableView.register(MuseumBannerCell.self, forCellReuseIdentifier: MuseumBannerCell.id)
tableView.register(MuseumNumberCell.self, forCellReuseIdentifier: MuseumNumberCell.id)
I have a tableView containing multiple cells which i can select but it doesn't display the label.text in it.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? ShowDeviceCell{
cell.setEntry(deviceName: devices_names[indexPath.row])
return cell
}
let cell = ShowDeviceCell()
cell.setEntry(deviceName: devices_names[indexPath.row])
return cell
}
And this is my cell definition:
class ShowDeviceCell: UITableViewCell {
#IBOutlet weak var deviceCell: UILabel! = {
let lbl = UILabel()
lbl.textColor = .black
lbl.font = UIFont.boldSystemFont(ofSize: 16)
lbl.textAlignment = .left
return lbl
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// addSubview(deviceCell)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setEntry (deviceName : String){
if let cellLabel = self.deviceCell{
cellLabel.text = deviceName
}
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
The error is the same whenever i try to use cell.deviceCell i got this error Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value.
Thanks for your help.
It worked, i have removed the register and the init methods. And by adding the right identifier of the cell in the storyboard. Thank you for your help.
I have a two custom cells implemented:
class TextFieldCell: UITableViewCell{
var label = UILabel()
var textField = UITextField()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
label.text = "Name"
textField.placeholder = "Enter Task Name Here"
addSubview(label)
addSubview(textField)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
class SwitchCell : UITableViewCell {
var label = UILabel()
var switchControl = UISwitch()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
label.text = "State"
switchControl.on = true
addSubview(label)
addSubview(switchControl)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
In my table view class i have declared this two cells:
let textFieldCell = TextFieldCell(style: .Default, reuseIdentifier: "textFieldCell")
let switchCell = SwitchCell(style: .Default, reuseIdentifier: "switchCell")
and have delegate method in it:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
switch indexPath.row {
case 0: return textFieldCell
case 1: return switchCell
default: return UITableViewCell()
}
}
But when table view loads i've see only switch control on the left of second row. I don't know why.
Try this:
private let reuseIdentifier = "switchCell"
//identifier of your cell.
Seems you have missed registering the cell.
let tableNib = UINib(nibName:"SwitchCell", bundle:nil)
self.tableView!.registerNib(tableNib,forCellReuseIdentifier:reuseIdentifier)
TextFieldCell Added below Code in ViewDidLoad of TableViewCell
self.tableView.registerClass(SwitchCell, forCellReuseIdentifier: "switchCell")
self.tableView.registerClass(TextFieldCell, forCellReuseIdentifier: "textFieldCell")
I am using parse and I have a PFQueryTableViewController inside a scrollView. When I load the app the data shows for a brief moment and then disappears. After I try to refresh the data the app immediately crashes. I think it has something to do with the permissions/delegate of the subViews because the same code works when the table is not inside the scrollView. The code for the table is just the default code pointing to my data
import UIKit
import Parse
import ParseUI
class CustomTableViewControllerA: PFQueryTableViewController {
override init(style: UITableViewStyle, className: String!){
super.init(style: style, className: className)
}
required init(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
//
self.parseClassName = "Countries"
self.textKey = "nameEnglish"
self.pullToRefreshEnabled = true
self.paginationEnabled = false
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("myCell") as! PFTableViewCell!
if cell == nil {
cell = PFTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "myCell")
}
if let nameEnglish = object?["nameEnglish"] as? String {
cell?.textLabel?.text = nameEnglish
}
if let capital = object?["capital"] as? String {
cell?.detailTextLabel?.text = capital
}
return cell
}
}
And the scrollView is made using storyboard in a CustomViewController
var AVC:CustomTableViewControllerA = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("CustomTableViewControllerA") as! CustomTableViewControllerA;
.
self.scrollView.addSubview(AVC.view)
and
self.scrollView.delegate = self
The frame settings for the scrollView/subViews are correct and I have not had a problem with that part of the code. The code runs without crashing when there is no internet connection, it just stays in a permanent refresh state.
I am using the below custom UITableViewCell without nib file.
I have no problem in viewing it in my UITableViewController.
My problem is with assigning a text to "name" label cell.name.text = "a Name" .. noting is assigned
Can you help me?
import UIKit
class ACMenuCell: UITableViewCell {
#IBOutlet var name : UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
name = UILabel(frame: CGRectMake(20, 10, self.bounds.size.width , 25))
name.backgroundColor = .whiteColor()
self.contentView.addSubview(name)
self.contentView.backgroundColor = .blueColor()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
super.layoutSubviews()
}
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
}
}
You might want to try this: Create a public function in a subclass of UITableViewCell, and inside this funxtion set the text to label.
(void)initializeCell
{
do whatever like setting the text for label which is a subview of tableViewCell
}
And from cellForRowAtIndexPAth, call this function on cell object:
// taking your code for demo
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let reuseIdentifierAC:NSString = "ACMenuCell"; var cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifierAC, forIndexPath:indexPath) as ACMenuCell cell = ACMenuCell(style: UITableViewCellStyle.Default, reuseIdentifier: reuseIdentifierAC) [cell initializeCell] return cell }
This approach has worked for me.