I'm having trouble loading the image in a default PFCollectionViewCell. I'm using the PFQueryCollectionViewController, and has set up the stuff properly - except for the imageFile.
The default PFCollectionViewCell has two fields: the PFImageView and the UILabel.
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFCollectionViewCell? {
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as? PFCollectionViewCell
if cell == nil {
cell = PFCollectionViewCell()
}
let nom = object as! Nom
cell?.imageView.file = nom.imageFile
println(nom.imageFile) //prints the object id
cell?.imageView.loadInBackground() //nothing actually loads
cell?.textLabel.text = nom.createdBy.name //textlabel is populated properly
return cell
}
I was able to populate the textField
I wasn't able to populate the imageView
What am I doing wrong?
Figured it out: You need to make sure you also put the placeholder image for it to load. You must set the image property of the PFImageView.
They should really document that...
Related
I have a custom class for UICollectionViewCell, but I am Unable to access a property in it called page in the ViewController.
What I have done :
1) I have created a property called page which is of type Page.
2) I have added custom class to the cell.
How about type force casting cell to PageCellCollectionViewCell using as!
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:
"cellID", for: indexPath) as! PageCellCollectionViewCell
let page = pages[indexPath.item]
cell.page = page
return cell
}
I want to attach information (a string) to each UITableViewCell when populating TableView with UITableViewCells. I don't want it to be visible- I just need to access this string when the row/cell is selected. What is the best way to do this?
Your best choice is probably to subclass UITableViewCell and add a string property. This can then be assigned either as a constant, or when setting up your cells in cellForRowAtIndexPath:.
class CustomCell: UITableViewCell {
var customString = "Default"
}
--------
func cellForRow(atIndexPath indexPath: IndexPath) -> UITableViewCell {
guard let cell: CustomCell = tableView.dequeueReusableCell(withReuseIdentifier: "identifier", indexPath: indexPath) as? CustomCell else {
return UITableViewCell()
}
cell.customString = "String"
return cell
}
func didSelectRow(atIndexPath indexPath: IndexPath) {
guard let cell: CustomCell = tableView.cellForRow(atIndexPath: indexPath) as? CustomCell else {
return
}
let stringFromCell = cell.customString
}
The above has not been compiled, so may not work word for word, but you get the principle.
Add a property selected to your model.
In cellForRow show/hide the string depending on the state of selected.
In didSelectRow toggle selected in the model and reload the row.
I am using a custom table view cell. This cell has a label with outlet called chatNameLabel. Adding a UILongPressGestureRecognizer to this label never fires the associated event.
I'm guessing that the problem is that the UILabel is in a TableView and that the table/cell view is intercepting the taps. Can I do something about this?
All I want to do is perform some custom action when a UILabel is long pressed!
I believe this was answered in Objective-C however I am not familiar with the language at all and new to swift.
Here's the code I'm using:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if let sessions = self.chatSessions where sessions.indices.contains(indexPath.row) {
let session = sessions[indexPath.row]
if session.sessionId == nil {
//DO A THING
}
// existing session id (existing chat)
else {
let cell = tableView.dequeueReusableCellWithIdentifier("ChatListCell", forIndexPath: indexPath) as! ChatListTableViewCell
cell.tag = indexPath.row
if(session.unreadChats) {
cell.indicatorImageView.tintColor = AppStyles.sharedInstance.indicatorActive
}
else{
cell.indicatorImageView.hidden = true
}
//Want to do gesture on this label below cell.chatNameLabel
cell.chatNameLabel.text = session.chatName
... Some more code not needed for question below this
Your class needs implement UIGestureRecognizerDelegate , then the below code should work.
myLabel.userInteractionEnabled = true
let tap: UILongPressGestureRecognizer = UILongPressGestureRecognizer(
target: self, action: #selector(tappedTheLabel))
tap.minimumPressDuration = 0.5
tap.delaysTouchesBegan = true
myLabel.addGestureRecognizer(tap)
tap.delegate = self
}
func tappedTheLabel(sender: UITapGestureRecognizer)
{
print("label hit \(sender)")
}
I'm using Xcode7.2.1 iOS9.2 SDK.
set the custom cell style with Right detail
Register cell nib:
Code:
self.TbuserList.registerNib(UINib.init(nibName: "UserCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: "idUserList")
set the cell detailTextLabel text:
Code:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("idUserList",forIndexPath: indexPath ) as! UserCell
//print(self.users)
cell.textLabel?.text = self.users[indexPath.row]["nickname"] as? String
cell.detailTextLabel?.text = (users[indexPath.row]["isConnected"] as! Bool) ? "Online" : "Offline"
cell.detailTextLabel?.textColor = (users[indexPath.row]["isConnected"] as! Bool) ? UIColor.greenColor() : UIColor.redColor()
return cell
}
Note:When I change the cell style from "Right detail" to "subtitle" or "Left detail", it's ok.
Since you are using a custom cell created from a xib file, I would advise avoiding trying to use the default cell elements (textLabel and detailTextLabel), and instead just add the views you need to create the cell you require. You can add additional views to the standard cells, but it can be a little more complicated to make sure your views work with the existing standard cell views. If a standard cell type would suit your needs, you can register the UITableViewCell class with the tableView instead of a custom xib file. Have a look at the section Customizing Cells in the Apple docs
I don't use Storyboard so I'm not sure if this is any help to you, but what I so in my custom cell is this:
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
//MARK: Setting ".value1" in super.init(style: .value1, ...) is the key to do this
super.init(style: .value1, reuseIdentifier: reuseIdentifier)
textLabel?.text = "Main Label"
detailTextLabel?.text = "Detail Label"
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
So long as you add a new Swift file and register the same names for your custom cell it should work.
What's the difference between this:
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
And this:
var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
They both seem t work fine for me.
PS: I know this seems to be an amateur question but i'm beginner in Xcode, so no reason to be a smug.
When you write :
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
You are initializing a new cell using its constructor.
And when you write :
var cell = self.tableView.dequeueReusableCellWithIdentifier("cell")
You are dequeuing a cell, so you are assuming your cell with the identifier cell has been already registered in the tableView.
Typically, if the cell was designed in Interface Builder and set as a prototype cell or if you have registered your cell for reuse using the method self.tableView.registerClass(MyCell.classForCoder(), forCellReuseIdentifier: "cell") you won't need to use the constructor because it is already initialized in the tableView.
But if your cell is designed programmatically such as creating UILabel, UIImage or whatever components, you will have to use the constructor instead, and then use the dequeue method.
So, if you have to use the constructor (because you're initializing everything by code) your code will look like this :
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
}
cell.cellLabel.text = "Hello world"
cell.cellImage.image = UIImage(named: "funny_cat.jpg")
return cell
}
But if your cell was registered for reuse or if it is a prototype cell you will just have to use
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.cellLabel.text = "Hello world"
cell.cellImage.image = UIImage(named: "funny_cat.jpg")
return cell
}
I think the best place to look how tableview work, you should look the official documentation here : Table View Programming Guide for iOS