Thread 1: EXC_BAD_INSTRUCTION Error - ios

Hi I've been trying to code a UITableView Custom Cell and when I ran it I keep getting the error "Thread 1: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, subcode=0x0)" on this line of code:
let cell: CustomCell = tableView.dequeueReusableCellWithIdentifier("Cell") as CustomCell
My full code is below
In ViewController.swift:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var mytableview: UITableView!
var arrayOfPersons: [Person] = [Person]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.setUpPersons()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setUpPersons()
{
var person1 = Person(name: "Anna", number: 60, imageName: "testingimage.jpg")
var person2 = Person(name: "Joes", number: 10, imageName: "testingimage2.jpg")
arrayOfPersons.append(person1)
arrayOfPersons.append(person2)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return arrayOfPersons.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: CustomCell = tableView.dequeueReusableCellWithIdentifier("Cell") as CustomCell
if indexPath.row % 2 == 0
{
cell.backgroundColor = UIColor.darkGrayColor()
}
else
{
cell.backgroundColor = UIColor.blackColor()
}
let person = arrayOfPersons [indexPath.row]
cell.setCell(person.name, rightlabelInt: person.number, imageName: person.imageName)
return cell
}
}
In CustomCell.Swift:
import UIKit
class CustomCell: UITableViewCell {
#IBOutlet weak var leftlabel: UILabel!
#IBOutlet weak var rightlabel: UILabel!
#IBOutlet weak var myimageview: UIImageView!
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
}
func setCell(leftlabelText: String, rightlabelInt: Int, imageName: String)
{
self.leftlabel.text = leftlabelText
self.rightlabel.text = String(rightlabelInt)
self.myimageview.image = UIImage(named: imageName)
}
}
And in Person.Swift:
import Foundation
class Person {
var name = "name"
var number = 0
var imageName = "blank"
init(name: String, number: Int, imageName: String)
{
self.name = name
self.number = number
self.imageName = imageName
}
}
I am not sure what the error means or if I made a mistake somewhere. Any help would be great!
Thanks!

I had a similar problem with a class inheriting from UITextView. The solution turned out to be I needed to override all the init methods.
override init()
{ super.init() }
override init(frame: CGRect, textContainer: NSTextContainer)
{ super.init(frame: frame, textContainer: textContainer) }
override init(frame: CGRect)
{ super.init(frame: frame) }
required init(coder aCoder: NSCoder)
{ super.init(coder: aCoder) }

Related

How to set customView in UITableViewCell with Swift

I have UITableView, UITablaViewCell, CustomView
and UITableViewCell includes customView.
I'm trying to put Product's data to cell with my function not cellForRowAt.
Cell shows just origin view ProductView.xib with empty data
Please help.
ViewController.swift
struct Product {
let brand: String
let product: String
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! ProductTableViewCell
// this line is not work
// productView is not update
cell.productView = createProductView(product: product)
return cell
}
func createProductView(product: Product) -> ProductView {
let productView = ProductView()
productView.brandLabel.text = product.brand
productView.productLabel.text = product.product
return productView
}
UITableViewCell.swift
class ProductTableViewCell: UITableViewCell {
#IBOutlet var productView: ProductView!
}
ProductView.swift
class ProductView: UIView {
#IBOutlet weak var productView: UIView!
#IBOutlet weak var brandLabel: UILabel!
#IBOutlet weak var productLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit(){
let bundle = Bundle(for: ProductView.self)
bundle.loadNibNamed("ProductView", owner: self, options: nil)
addSubview(productView)
productView.frame = self.bounds
}
There are multiple issues with your code
Issue 1: cellForRowAt IndexPath gets called multiple times, with your code you will end up creating a new ProductView every time tableView is scrolled (cell is reused). instead you can create product view only once and update its label every time cell is reused
Issue 2: In ProductView's commonInit you set the frame using productView.frame = self.bounds self.bounds will always be(0,0,0,0). Because you have instantiated ProductView as ProductView()
Issue 3: createProductView is supposed to return an instance of ProductView hence the method signature is invalid so you should change it from func createProductView(product: Product) -> ProductView() to func createProductView(product: Product) -> ProductView as already suggested in answer above
What can be better solution?
class ProductTableViewCell: UITableViewCell {
var productView: ProductView!
func updateProductView(product: Product) {
productView.brandLabel.text = product.brand
productView.productLabel.text = product.product
}
override func prepareForReuse() {
super.prepareForReuse()
productView.brandLabel.text = nil
productView.productLabel.text = nil
}
override func awakeFromNib() {
super.awakeFromNib()
self.productView = createProductView()
self.addSubview(self.productView)
self.productView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
self.productView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
self.productView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
self.productView.topAnchor.constraint(equalTo: self.topAnchor),
self.productView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
}
func createProductView() -> ProductView {
return ProductView()
}
}
Finally in your cellForRowAtIndexPath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! ProductTableViewCell
//assuming you already have a product for index path
cell.updateProductView(product: product)
return cell
}
EDIT:
As OP is facing issue with loading nib from bundle updating the answer here.
In your ProductView common init change the way you access bundle from
Bundle(for: ProductView.self) to Bundle.main as shown below
class ProductView: UIView {
#IBOutlet weak var productView: UIView!
#IBOutlet weak var brandLabel: UILabel!
#IBOutlet weak var productLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit(){
Bundle.main.loadNibNamed("ProductView", owner: self, options: nil)
addSubview(productView)
}
Few things to take care
Ensure you have an XIB named ProductView in your bundle
Ensure you have set its file owner to ProductView

NSInvalidArgumentException : Workout_Tracker.QuickAddViewController collectionView:numberOfItemsInSection:]: unrecognized selector sent to instance

I have a class MenuTabs: UIView that corresponds to MenuTabs.xib. I linked them in the identity inspector. In the view is a UICollectionView. I set the UIView as the delegate and datasource for the collection view in storyboard. I'm using the MenuTabs class in a ViewController, but I keep getting this error
'NSInvalidArgumentException', reason: '-[Workout_Tracker.QuickAddViewController collectionView:numberOfItemsInSection:]: unrecognized selector sent to instance 0x7fbbe970a120'
Here are my MenuTabs and QuickAddViewController files
import UIKit
class MenuTabs: UIView {
let workoutTypes = ["", "", "", ""]
let cellId = "cellId"
#IBOutlet weak var contentView: UIView!
#IBOutlet weak var collectionView: UICollectionView!
override init(frame: CGRect) {
super.init(frame: frame)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
if self.subviews.count == 0 {
self.setup()
}
}
func setup() {
Bundle.main.loadNibNamed("MenuTabs", owner: self, options: nil)
guard let content = contentView else { return }
contentView.frame = self.bounds
contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
addSubview(content)
}
}
// MARK: - Delegate and Datasource methods for UICollectionView
extension MenuTabs: UICollectionViewDelegate, UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return workoutTypes.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
cell.backgroundColor = UIColor.red
return cell
}
}
import UIKit
class QuickAddViewController: UIViewController {
enum MuscleGroup: String {
case abs = "Abs"
case arms = "Arms"
case back = "Back"
case calves = "Calves"
case chest = "Chest"
case legs = "Glutes & Legs"
case shoulders = "Shoulders"
}
enum WorkoutType: String {
case bodyWeight = "Body Weight"
case weightTraining = "Weight Training"
case sportsAndRecreation = "Sports & Recreation"
case cardio = "Cardio"
}
#IBOutlet weak var workoutTypesMenu: UIView!
let exercisesData = ExerciseDatabase()
var workoutTypesDictionary = Dictionary<String,Dictionary<String,Array<String>>>()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
workoutTypesDictionary = self.exercisesData.exercisesByWorkoutType
tabBarController?.tabBar.isTranslucent = false
// Load workoutTypesMenu View
if let wtMenu = Bundle.main.loadNibNamed("MenuTabs", owner: self, options: nil)?.first as! MenuTabs? {
workoutTypesMenu.addSubview(wtMenu)
}
}
// MARK: - Get data from ExerciseDatabase.swift
// Get the workout types
func getWorkoutTypes() -> [String] {
var workoutTypesArray : [String] = []
for workoutType in workoutTypesDictionary.keys {
workoutTypesArray.append(workoutType)
}
return workoutTypesArray
}
// Get the list of muscles or options
func getMusclesOrOptions(for workoutType: String) -> [String] {
var musclesOrOptionsArray : [String] = []
let musclesOrOptions = workoutTypesDictionary[workoutType]!.keys
for muscleOrOption in musclesOrOptions {
musclesOrOptionsArray.append(muscleOrOption)
}
return musclesOrOptionsArray
}
// Get the list of exercises
func getExercisesArray(for workoutType: String, for muscleOrOption: String) -> [String] {
var exercisesArray : [String] = []
exercisesArray = workoutTypesDictionary[workoutType]![muscleOrOption]!
return exercisesArray
}
// Get the selected exercise
func getSelectedExercise(in workoutType: String, for muscleOrOption: String, at index: Int) -> String {
var selectedExercise : String = ""
selectedExercise = workoutTypesDictionary[workoutType]![muscleOrOption]![index]
return selectedExercise
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - WorkoutTypesBar and Muscles and Options Bar
// Set up the WorkoutTypes bar and the muscles and option types bar
}
Instead of setting up the delegate and datasource through the nib file, I set them in the init method of MenuTabs.swift
override init(frame: CGRect) {
super.init(frame: frame)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId)
setup()
}

FirebaseUi - Cast value of UITableViewCell to custom class in swift

I can t seem to get the prototypereuseidentifier thing on firebaseUI. If I add a prototypecell, I can only give it a cellidentifier
In my following code, my IBoutlets linked to my custom cell return nil.
here s my code :
func loadData() {
self.dataSource = FirebaseTableViewDataSource(ref: refpost, cellClass: MainWitnessTableViewCell.self, cellReuseIdentifier: "<RIcell>", view: self.tableView)
self.dataSource.populateCellWithBlock { (cell: UITableViewCell, obj: NSObject) -> Void in
let snap = obj as! FDataSnapshot
print(cell)
let mycell = cell as! MainWitnessTableViewCell
let keyy: String = (snap.value.objectForKey("author") as? String)!
mycell.postContent.text = keyy
print (mycell.postContent.text)
}
self.tableView.dataSource = self.dataSource
}
here, mycell.postContent.text returns nil, is there any sorcery that keeps blinding me ? :)
sincerely
Yann
I think you should change
cellReuseIdentifier: "<RIcell>"
to
cellReuseIdentifier: "RIcell"
# jonas : here s the cell class
class MainWitnessTableViewCell: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var cellImage: UIImageView!
#IBOutlet weak var postOwner: UILabel!
#IBOutlet weak var postDate: UILabel!
#IBOutlet weak var postContent: UITextView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
postContent.text = ""
postOwner.text = ""
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}

Having trouble passing property into drawRect in UIView

Not understanding why my property resets to the original value assigned (0.1). I pass in a fillHeight of 0.5 from outside method. The property is set in the convenience init, but does not carry over to the drawRect. What am I missing?
import UIKit
class MyView: UIView {
var fillHeight: CGFloat = 0.1
override init(frame: CGRect) {
super.init(frame: frame)
}
convenience init(fillHeight: CGFloat) {
self.init()
self.fillHeight = fillHeight
print("self.fillHeight: \(self.fillHeight) and fillHeight: \(fillHeight)")
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
override func drawRect(rect: CGRect) {
print("drawRect self.fillHeight: \(self.fillHeight)")
// custom stuff
}
}
Output on the console:
outsideAmount:Optional(0.5)
self.fillHeight: 0.5 and fillHeight: 0.5
drawRect self.fillHeight: 0.1
EDIT:
The outside call comes from UITableViewController with a custom UITableViewCell. The image is for the cell.
func configureCell(cell: CustomTableViewCell, atIndexPath indexPath: NSIndexPath) {
let myObject = self.fetchedResultsController.objectAtIndexPath(indexPath) as! MyObject
cell.nameLabel.text = myObject.name
cell.strengthLabel.text = myObject.strength
cell.myView = MyView(fillHeight: CGFloat(myObject.fillAmount!))
...
MORE EDIT:
import UIKit
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var strengthLabel: UILabel!
#IBOutlet weak var myView: MyView!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
The problem is that you assign a new MyView instance whenever you configure your cell. You don't have to do that because the view is already there (because you added it in the nib).
So just set fillHeight on the cell's myView. That fixes the problem:
func configureCell(cell: CustomTableViewCell, atIndexPath indexPath: NSIndexPath) {
let myObject = self.fetchedResultsController.objectAtIndexPath(indexPath) as! MyObject
cell.nameLabel.text = myObject.name
cell.strengthLabel.text = myObject.strength
cell.myView.fillHeight = CGFloat(myObject.fillAmount!)
....
}

Swift fatal error: unexpectedly found nil while unwrapping an Optional value (lldb) in Tableview [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have custom cell in table view. When I am running my code I am getting
below error
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
My code is below:
class viewCompanyResultController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var uiTblCompanyResultView: UITableView!
var companyName=""
var countryCode=""
var townCode=""
var element=""
var resultDict: NSDictionary=[:]
var comapniesArr:[Company] = [Company]()
override func viewDidLoad() {
super.viewDidLoad()
self.uiTblCompanyResultView.delegate=self
self.uiTblCompanyResultView.dataSource=self
self.comapniesArr.append(Company(orgName: "cbre", orgCode: "orgCode2", imageName: "3.png"))
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
return self.comapniesArr.count
}
func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell {
let cell: CompantResultCell = tableView .dequeueReusableCellWithIdentifier("cell") as CompantResultCell
let companyResult=comapniesArr[indexPath.row]
println("dgfdf \(companyResult.orgName)")
cell.setCompanyCell(uiImgConComp: companyResult.imageName,lblCompanyName: companyResult.orgName)
return cell
}
}
Custome Cell Class
import UIKit
class CompantResultCell: UITableViewCell {
#IBOutlet var uiImgConComp: UIImageView!
#IBOutlet var lblCompanyName: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init(coder aDecoder: NSCoder) {
//fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func setCompanyCell(imageName: String,lblCompanyName: String)
{
self.uiImgConComp.image=UIImage(named: imageName)
self.lblCompanyName.text=lblCompanyName;
}
}
Custom cell class looks perfect!
You need to unwrapped custom cell object in tableView:(_cellForRowAtIndexPath:) method like below:
func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell {
var cell: CompantResultCell! = tableView .dequeueReusableCellWithIdentifier("cell") as? CompantResultCell
if (cell == nil) {
cell = CompantResultCell(style: UITableViewCellStyle.Default, reuseIdentifier:"cell")
}
let companyResult=comapniesArr[indexPath.row]
println("dgfdf \(companyResult.orgName)")
cell.setCompanyCell(uiImgConComp: companyResult.imageName,lblCompanyName: companyResult.orgName)
return cell
}
Edit:
Also unwrapped UIImage object in setCompanyCell method:
func setCompanyCell(imageName: String,lblCompanyName: String) {
var cellImage = UIImage(named: imageName as String!) as UIImage!
self.uiImgConComp.image = cellImage
self.lblCompanyName.text=lblCompanyName;
}
Calling the function behaviour is different in Swift, not like in Objective C. Call this function as below line:
cell.setCompanyCell(companyResult.imageName, lblCompanyName: companyResult.orgName)

Resources