I am working with Xcode 7 and swift.
I am trying to connect a label that is on a Collection View prototype cell to my code. I know to do this, I have to make a subclass of UICollectionViewCell and put it in that class instead of the view controller, which I did. I run the app immediately after adding the outlet to the subclass, and the app crashes. I noticed at the top of the error message it says: Unknown Class nameOfSubclass in Interface Builder File. I have looked at other stack overflow questions and they say it is a simple matter of setting the module under the custom class. I did this, but the app still crashes and now it says: Unknown class _TtC13 (app name / module name) 17(nameOfSubclass) in Interface Builder file.
identity inspector of the prototype cell
identity inspector of the UICollectionView
Code
import UIKit
class SecondViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var collectionView: UICollectionView!
private let reuseIdentifier = "hourlyWeatherCell"
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return 48
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) //as! hourlyWeatherCell
// Configure the cell
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
printDate()
// Do any additional setup after loading the view.
self.collectionView.dataSource = self
self.collectionView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
class hourlyWeatherCell: UICollectionViewCell {
#IBOutlet weak var temperatureHLabel: UILabel!
}
}
With a little tinkering I got it to work. For some reason Xcode was not compiling the subclass it the UIViewContoller. I simply moved the subclass out of the view controller class (making the subclass a class), and everything worked fine.
Related
I coded my first CollectionView but the build fails with this error message:
"Illegal Configuration: The myLabel outlet from the UICollectionView to the UILabel is invalid. Outlets cannot be connected to repeating content."
I read other questions on StackOverflow with the same error, and the solution was to set the content of the UILabel which is in a prototype cell and has an outlet to "CollectionViewCell.swift" from static to dynamic. I couldn't try this because this option doesn't appear. I think it's gone with the newer versions of Xcode.
My code in "CollectionViewCell.swift":
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var myLabel: UILabel!
}
My code in "ViewController.swift":
class LibraryViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
#IBOutlet weak var sortCollectionView: UICollectionView!
func numberOfSections(in sortCollectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ sortCollectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ sortCollectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let sortCell = sortCollectionView.dequeueReusableCell(withReuseIdentifier: "sortCell", for: indexPath) as! CollectionViewCell
sortCell.myLabel.text = "hi"
return sortCell
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
Thank you for every helpful answer :'D
Select your UILabel from Storyboard and check connections of it, there might be an old connection of it. Remove that old connection and you are good to go.
Ok, I fixed it by myself!
For everyone who search for the solution:
Double check if there are no other Outlets than the CollectionViewCell!
In my case the Label had an outlet to another thing :^)
I was following a coding tutorial of making a simple app, everything looked and worked okay at first but after a while I ran into an error says:
use of unresolved identifier 'UITableViewCell'.
The tutorial's code worked fine in its video and I wrote the exact same code however it was an error on my computer. I guess it's the matter of different versions of Xcode.
Here is my code:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.dataSource = self
self.tableView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 6
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
**let cell = UITableviewCell()**
*//Where the error message is at. //*
return cell
}
}
The error message is at the line:
let cell = UITableViewCell()
I cannot comment on the answer posted by Stefan Salatic but you have to indeed use dequeable cells but to add to that, you should not forget to set the identifier in the main.storyboard to the CellIdentifier you used to create dequeable cell.
let cell = tableView.dequeueReusableCellWithIdentifier("Identifier", forIndexPath: indexPath) as UITableViewCell
In the storyboard go to the TableViewController -> Attribute Inspector -> Identifier and set it to:
Identifier
If you have an array of data you can fill the cell using:
cell!.textLabel?.text = data[indexPath.row]
You should dequeue UITableViewCells. Something like this
let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as UITableViewCell
You want to reuse cells, not create a new one each time. This is the preferred way of doing it.
I'm trying to have a better understanding on how the dataSource and delegate outlets get connected to the UITableView under the hood when you do the connection through the UI in Xcode by dragging and dropping to the viewController icon.
I found this thread but I think I'm missing something because I cannot make it work.
Here is the code I currently have that works fine by connecting the outlets through XCode (by drag and dropping).
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var hobbies:[String] = ["Computers", "Photography", "Cars", "Reading", "Learning New Things"]
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return hobbies.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = hobbies[indexPath.row]
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
// 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.
}
}
I tried removing the outlet connections made by XCode, created an outlet for the tableView (myTable) and added the following code in the viewDidLoad method but it doesn't work, no error it just doesn't load the data.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
myTable.delegate = self
myTable.dataSource = self
}
Can someone describe the steps needed to do this connection with code?
Just for reference here are the steps needed to do your connection programmatically.
1.- Create outlet for tableView
#IBOutlet weak var myTable: UITableView!
2.- Assign delegate and dataSource in the viewDidLoad method.
myTable.delegate = self
myTable.dataSource = self
3.- DONE
There are a couple of ways to do it.
1. The simplest one is by dragging and dropping:
In your main.storyboard select your TableView;
Press your Control button;
Click and drag the mouse from your TableView to your ViewController's icon and drop it;
Then select dataSource and delegate as shown on the image above.
2. The other way is by coding:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
}
PS: Make sure not to forget connecting your tableView outlet to your code by dragging and dropping it into your ViewController class.
PPS: It'll also ask you to implement the following methods into your class so that your tableView works properly:
numberOfRowsInSection
cellForRowAtIndexPath
For those who don't have them yet, you'll see Xcode complaining about it.
I am new to Swift, and iOS development in general. I am attempting to create a custom UITableViewCell. I have created the cell in my main storyboard on top of a UITableView that is inside a UIViewController. When I loaded one of the default cells, I was able to populate it with data. However, now that I am using a custom cell, I cannot get any data to appear in the table. I have gone through all kinds of tutorials and questions posted on the internet, but I can't figure out why it is not working. Any help would be appreciated.
Here is my code for the UIViewController that the tableview resides in.
import UIKit
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tblView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//self.tblView.registerClass(UITableViewCell.self, forCellReuseIdentifier : "Cell")
self.tblView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier : "Cell")
tblView!.delegate = self
tblView!.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataMgr.data.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : CustomTableViewCell = self.tblView.dequeueReusableCellWithIdentifier("Cell", forIndexPath : indexPath) as! CustomTableViewCell
var values = dataMgr.data[indexPath.row]
cell.newTotalLabel?.text = "\(values.newTotal)"
cell.winLoseValueLabel?.text = "\(values.newTotal - values.currentTotal)"
cell.dateLabel?.text = "5/17/2015"
return cell
}
}
I have stepped through the program where it is assigning values to the cell variables. The variable 'values' is being populated with data, but when stepping over the assignment lines to the cell variables, I found that they are never assigned. They all remain nil.
When you make a custom cell in the storyboard, don't register the class (or anything else). Just be sure to give the cell the same identifier in the storyboard that you pass to dequeueReusableCellWithIdentifier:forIndexPath:.
My UITableView data source and delegate are not connected to any file. If this is the problem, would someone tell me how to connect them. If not, here is my code.
My File containing the struct info:
struct PreviousApps {
var name : String
var description : String
var filename : String
}
And this is my code in my TableViewController:
import UIKit
class PreviousProjectsVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
var apps = [PreviousApps]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var PreviousApp = PreviousApps(name: "Gecko Catch", description: "DESCRIPTION", filename: "geckocatch.png")
apps.append(PreviousApp)
PreviousApp = PreviousApps(name: "Flappy Timothy", description: "DESCRIPTION", filename: "flappytimothy.png")
apps.append(PreviousApp)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
var currentApp = apps[indexPath.row]
cell.textLabel!.text = currentApp.name
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return apps.count
}
}
I am new to Swift and any help would be appreciated. If i'm not being specific enough, tell me and I will try to provide you with more info.
Thanks,
Beck
Assuming that you are using storyboard to set up your tableviewcontroller:
Set PreviousProjectsVC as the class for the table view controller using identity inspector (at right panel in Xcode)
Click on the "Show document outline" at the bottom-left corner in storyboard
Select the TableView from the outline and control + drag from there to the yellow icon at the top of the table view controller scene in storyboard
Select delegate and datasource from the menu displayed
To set the delegate and datasource from the code, create an outlet for the TableView and set tableView.delegate = self and tableView.dataSource = self