I'm getting the "thread 1: exc_bad_access (code=2, address=0x16fc0bfefe8) error. I have set up the iOS app to access a Table View Controller after logging in. It should display images. I have been following this tutorial http://shrikar.com/uitableview-and-uitableviewcell-customization-in-swift/ but no luck. This is my data.swift file where the error originates from:
import Foundation
class Data {
class Entry: Data {
let filename : String
init(fname : String) {
self.filename = fname
}
}
let products = [
Entry(fname: "placeholder1"), // <- Thread 1 error code shows in this line
Entry(fname: "placeholder2"),
Entry(fname: "placeholder3")
]
}
HomeTableViewController.swift
import UIKit
class HomeTableViewController: UITableViewController {
let data = Data()
override func viewDidLoad() {
super.viewDidLoad()
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.products.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! HomeTableViewCell
let entry = data.products[indexPath.row]
let image = UIImage(named: entry.filename)
cell.bkImageView.image = image
return cell
}
HomeTableViewCell.swift
import UIKit
class HomeTableViewCell: UITableViewCell {
#IBOutlet weak var bkImageView: UIImageView!
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
}
}
Humbly asking for some assistance. Thanks in advance.
The issue is this line:
class Entry: Data {
Since Entry inherits from Data when you create an instance of Data the program goes into an infinite loop of initializing both the first member of products (an Entry) and its parent class, Data. Instead it should be this, as per the tutorial:
class Entry {
Related
I'm having a problem in which my custom UITableView will not show up when I build my application.
Currently, I've built what the custom table should look like in my storyboard and also have created a cocoa class that is linked to the UITableViewCell.
This is the ViewController code that deals with retrieving the input form an array and then pasting it onto the table
import UIKit
struct eventStruct
{
let eventHost : String
let eventStatus : String
let eventPrice : String
}
class eventsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var eventArrayData = [eventStruct]()
override func viewDidLoad() {
super.viewDidLoad()
eventArrayData = [eventStruct(eventHost: "Event1", eventStatus: "OPEN", eventPrice: "$5"),
eventStruct(eventHost: "Event2", eventStatus: "CLOSED", eventPrice: "$0")]
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return (eventArrayData.count)
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let eventCell = tableView.dequeueReusableCell(withIdentifier: "eventTemplate", for: indexPath) as! eventsTableViewCell
eventCell.eventHost.text = eventArrayData[indexPath.row].eventHost
eventCell.eventPrice.text = eventArrayData[indexPath.row].eventPrice
eventCell.eventStatus.text = eventArrayData[indexPath.row].eventStatus
return (eventCell)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Any extra information that is needed and/or help would be really appreciated!
You have not connected delegate to your view controller
you can connect your delegate in two ways
1) Using viewDidLoad() function
override func viewDidLoad() {
super.viewDidLoad()
yourTableVeiw.delegate = self
yourTableView.dataSource = self
}
2) Using storyboard
just drag and drop on your view controller
follow below image
I want to show a button on my custom UITableViewCell which takes the user to another screen on tapping on it.
I have tried following code but it doesn't work
Child view:
#IBAction func childScreenButton(sender: AnyObject) {
if let delegate = self.delegate {
delegate.childButtonClickedOnCell(self)
}
}
Protocol:
protocol childTableCellDelegate: class {
func childButtonClickedOnCell(cell: childViewCell)
}
Parent ViewController:
func childButtonClickedOnCell(cell: FeedChildViewCell) {
self.clickedIndexPath = self.feedsTableView.indexPathForCell(cell)
self.performSegueWithIdentifier("toNextScreen", sender: self)
}
while I'm testing the break point doesn't enter into "delegate.childButtonClickedOnCell(self)" on child view. Please let me know if am doing anything wrong here. Thanks!!
I suspect you've got a couple things out of place, or not defined just right.
I just ran a quick test with this, and the delegate call works fine... see if you notice anything not-quite-the-same...
//
// TestTableViewController.swift
//
// Created by DonMag on 4/7/17.
// Copyright © 2017 DonMag. All rights reserved.
//
import UIKit
protocol MyCellDelegate {
func pressedButtonForMyCell(theSender: MyCell)
}
class MyCell: UITableViewCell {
#IBOutlet weak var theLabel: UILabel!
#IBOutlet weak var theButton: UIButton!
var delegate: MyCellDelegate?
#IBAction func childScreenButton(sender: AnyObject) {
delegate?.pressedButtonForMyCell(theSender: self)
}
}
class TestTableViewController: UITableViewController, MyCellDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyCell
cell.theLabel.text = "\(indexPath)"
cell.delegate = self
return cell
}
func pressedButtonForMyCell(theSender: MyCell) {
print("delegate called", theSender)
}
}
I'm updating existing Objective-C app.
There is a structure:
AppDelegate
- creates mainBackgroundView and adding subview with UITabBarController
I have in one "Tab" HistoryViewController:
#objc class HistoryViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let historyTableViewController = HistoryTableViewController()
self.view.addSubview(historyTableViewController.view)
}
}
And HistoryTableViewController:
import UIKit
#objc class HistoryTableViewController: UITableViewController {
// Mark: properties
var historyCalls = [HistoryItem]()
// Mark: private methods
private func loadSimpleHistory() {
let hist1 = HistoryItem(personName: "Test", bottomLine: "text", date: "10:47")
let hist2 = HistoryItem(personName: "Test 2", bottomLine: "text", date: "10:47")
let hist3 = HistoryItem(personName: "Test 3", bottomLine: "text", date: "10:47")
historyCalls += [hist1, hist2, hist3]
}
override func viewDidLoad() {
super.viewDidLoad()
self.loadSimpleHistory()
self.tableView.register(UINib(nibName: "HistoryCallTableViewCell", bundle: nil), forCellReuseIdentifier: "HistoryCallTableViewCell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return historyCalls.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "HistoryCallTableViewCell", for: indexPath) as? HistoryCallTableViewCell else {
fatalError("Coulnd't parse table cell!")
}
let historyItem = historyCalls[indexPath.row]
cell.personName.text = historyItem.personName
cell.bottomLine.text = historyItem.bottomLine
cell.date.text = historyItem.date
return cell
}
}
When I open the navigation tab with HistoryViewController for the first time, table appers with data. When I click into the table or switch navTab and then go back, table is not there anymore.
When I switch to another app and then go back, table is there again.
How to fix this?
Thank you
Call data method in viewwillappear and reload the table..
override func viewWillAppear() {
super.viewWillAppear()
self.loadSimpleHistory()
self.tableview.reloadData()
}
I'm following a swift development course for beginners and am trying to make a very simple app that creates new tasks with an entered text once a button is pressed, but I am encountering a few errors that I can't seem to understand.
The errors happen in my ViewController and the editor tells me my Core Data Entity does not possess an attribute named "corename" while it very well does.
Here is a screenshot of the errors : 3 errors
And here is my code :
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var tasks : [Taskentity] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
//Get the data from Core data
getData()
//Reload the table view
tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return tasks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath : IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let task = tasks[indexPath.row]
if (task.isImportant == true){
cell.textLabel?.text = "😅 \(tasks.corename!)"
} else {
cell.textLabel?.text = tasks.corename!
}
return cell
}
func getData() {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
do {
tasks = try context.fetch(Taskentity.fetchRequest())
} catch {
print("Fetching Data")
}
}
}
Tasks is a Array of Taskentities, you probably meant to access task.corename not tasks.corename
if (task.isImportant == true){
cell.textLabel?.text = "😅 \(task.corename!)"
} else {
cell.textLabel?.text = task.corename!
}
And for the TableViewDelegate problem, just make sure to implement all necessary funcs... You are missing 1:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
I have a tableview controller with a custom Prototype Cell. The cell contains 2 labels. I am trying to return 2 values from a Parse class. One field is called Notes and is a String value. The other field is called CreditAmount and is a number value. I am having difficulty returning the number value (Credit Amount) in my tableview.
Here is code for tableview controller:
import UIKit
import Parse
import Foundation
class TableViewController: UITableViewController {
var note = [String]()
var credit = [NSInteger]()
var refresher: UIRefreshControl!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.reloadData()
updateNotes()
self.refresher = UIRefreshControl()
self.refresher.attributedTitle = NSAttributedString(string: "Pull to refresh")
self.refresher.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(refresher)
}
func updateNotes() {
let query = PFQuery(className: "Paydown")
query.findObjectsInBackgroundWithBlock({ (objects:[AnyObject]?, error: NSError?) -> Void in
self.note.removeAll(keepCapacity: true)
self.credit.removeAll(keepCapacity: true)
if let objects = objects as? [PFObject] {
for object in objects {
// var noted = object as PFObject
self.note.append(object["Notes"] as! String)
self.credit.append(object["CreditAmount"] as! NSInteger)
}
self.tableView.reloadData()
} else {
//println(error)
}
self.refresher.endRefreshing()
})
}
func refresh() {
updateNotes()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return note.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! cell
myCell.notesLabel.text = note[indexPath.row]
myCell.amountLabel.text = credit[indexPath.row]
return myCell
}
}
Here is the code for my customer cell:
import UIKit
import Parse
class cell: UITableViewCell {
#IBOutlet weak var notesLabel: UILabel!
#IBOutlet weak var amountLabel: UILabel!
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
}
}
The myCell.amountLabel.text = credit[indexPath.row] causes an error: cannot assign a value of type NSInteger (aka int) to a value of type String?. How do I get the number field to work?
Update
myCell.amountLabel.text = credit[indexPath.row]
To be
myCell.amountLabel.text = "\(credit[indexPath.row])"