Hi Im programming an chat app and i wan't the profile pictures to have a corner radius. This is my code. Btw Im using Parse as backend.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
var imageView = PFImageView()
let user = self.users[indexPath.row]
imageView.layer.cornerRadius = imageView.frame.size.width / 2
imageView.layer.masksToBounds = true
imageView.file = user[PF_USER_PICTURE] as? PFFile
cell.textLabel?.text = user[PF_USER_FULLNAME] as? String
cell.textLabel?.font = UIFont.boldSystemFontOfSize(24)
cell.imageView?.image = imageView.image
return cell
}
UPDATE:
The problem was that my cell.imageview did not have a frame.
Thanks for the answer Max K!
var imageView = PFImageView()
is a different image view than:
cell.imageView?.image = imageView.image
What shows on screen is the image view of your cell not this instance of PFImageView. If you want to have PFImageView in as a class of your's cell's image view you need to set that, either in the storyboard or by subclassing your cell.
You applied cornerRadius to layer of imageView created here:
var imageView = PFImageView()
But then you are using only its image property and assigning it to cell`s imageView:
cell.imageView?.image = imageView.image
Apply cornerRadius to cell's imageView.
You are setting cornerRadius on imageView that is not added to the screen later.
You have to set it on cell.imageView
if let imageView = cell.imageView {
imageView.layer.cornerRadius = imageView.frame.size.width / 2
}
You are adding corner to the imageView in
var imageView = PFImageView()
Instead add corner to the cell.imageView. It seems like you are using PFImageView to download image from a file. So you can modify the code like
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
var imageView = PFImageView()
let user = self.users[indexPath.row]
cell.imageView.layer.cornerRadius = imageView.frame.size.width / 2
cell.imageView.layer.masksToBounds = true
imageView.file = user[PF_USER_PICTURE] as? PFFile
cell.textLabel?.text = user[PF_USER_FULLNAME] as? String
cell.textLabel?.font = UIFont.boldSystemFontOfSize(24)
cell.imageView?.image = imageView.image
return cell
}
Or else make imageView of cell.imageView as PFImageView
Related
Screenshot of the double text label
Current constraints of the label
Complete Hirearchy
What is my relevant code currently
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ViewControllerTableViewCell {
let immy = cell.viewWithTag(1) as? UIImageView
let person: Userx = people[indexPath.row]
let text = person.Education
cell.lblName.text = person.Education. ///key line
cell.lblName.text = text?.uppercased()
cell.lblName?.layer.masksToBounds = true
let person5 = colorArray[indexPath.row]
let person6 = colorArray1[indexPath.row]
let person7 = colorArray2[indexPath.row]
let like = cell.viewWithTag(3) as? UIButton
cell.backgroundColor = person5
like?.backgroundColor = person6
immy?.backgroundColor = person7
cell.lblName.baselineAdjustment = .alignCenters
cell.postID = self.people[indexPath.row].postID
cell.row = indexPath.row
cell.delegate = self
cell.delegate2 = self
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
like?.isUserInteractionEnabled = true
}
return cell
}
return UITableViewCell()
}
What have I tried:
In prepare for reuse, I tried lblName.text = "" and lblName.text = nil Didn't work.
I also tried in cellForRowAt:
cell.lblName.text = nil
if cell.lblName.text == nil{
cell.lblName.text = person.Education
}
I also tried to get it done by constraints, no luck.
What I think might be cause
This didn't happen before I changed from TableViewController scene to ViewController(with an output table) scene.
It also didn't happen before I set the cells to have different colors.
I got it to work by checking clear graphics context on label2.
i think your problem would solve if you check cell heights ,
check heightForCellAtRow Func
I havent seen at your cell class. That issue happens when you have constraints issues. Since the autolayout system is unable to calculate the height of the row, the height becomes 0, any change from that point forward might be wrong.
I would suggest you check the cell code, add the labels to the contentView (if they are not) and add constraints between them:
eg:
bottomLabel.topAnchor.constraint(equalTo: topLabel.bottomAnchor, constant: 8).isActive = true
also set the compression resistance for both labels to be .defaultHigh and if you have the height of the row hardcoded remove that.
I've made an UITableView and filled it with JSON data I get inside my API. I get and place all correctly but when I scroll or delete a row everything gets messed up!
Labels and images interfere; this is my code:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
var dict = productsArrayResult[indexPath.row]
let cellImage = UIImageView(frame: CGRect(x: 5, y: 5, width: view.frame.size.width / 3, height: 90))
cellImage.contentMode = .scaleAspectFit
let productMainImageString = dict["id"] as! Int
let url = "https://example.com/api/DigitalCatalog/v1/getImage?id=\(productMainImageString)&name=primary"
self.downloadImage(url, inView: cellImage)
cell.addSubview(cellImage)
let cellTitle = UILabel(frame: CGRect(x: view.frame.size.width / 3, y: 5, width: (view.frame.size.width / 3) * 1.9, height: 40))
cellTitle.textColor = UIColor.darkGray
cellTitle.textAlignment = .right
cellTitle.text = dict["title"] as? String
cellTitle.font = cellTitle.font.withSize(self.view.frame.height * self.relativeFontConstantT)
cell.addSubview(cellTitle)
let cellDescription = UILabel(frame: CGRect(x: view.frame.size.width / 3, y: 55, width: (view.frame.size.width / 3) * 1.9, height: 40))
cellDescription.textColor = UIColor.darkGray
cellDescription.textAlignment = .right
cellDescription.text = dict["description"] as? String
cellDescription.font = cellDescription.font.withSize(self.view.frame.height * self.relativeFontConstant)
cell.addSubview(cellDescription)
return cell
}
You are adding subviews multiple times while dequeuing reusable cells. What you can do is make a prototype cell either in storyboard or as xib file and then dequeue that cell at cellForRowAtIndexPath.
Your custom class for cell will look similar to this where outlets are drawn from prototype cell.
Note: You need to assign Reusable Identifier for that prototype cell.
class DemoProtoTypeCell: UITableViewCell {
#IBOutlet var titleLabel: UILabel!
#IBOutlet var descriptionLabel: UILabel!
#IBOutlet var titleImageView: UIImageView!
}
Now you can deque DemoProtoTypeCell and use accordingly.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: DemoProtoTypeCell.self), for: indexPath) as! DemoProtoTypeCell
cell.titleImageView.image = UIImage(named: "demoImage")
cell.titleLabel.text = "demoTitle"
cell.descriptionLabel.text = "Your description will go here."
return cell
}
That's because you are adding subviews to reused (so that it may already have subviews added previously) cells.
Try to check if the cell has subviews and fill in information you need, if there're no subviews then you add them to the cell.
Option 1
if let imageView = cell.viewWithTag(1) {
imageView.image = //your image
} else {
let imageView = UIImageView(//with your settings)
imageView.tag = 1
cell.addSubview(imageView)
}
Option 2
Crete UITableViewCell subclass that already has all the subviews you need.
I have used below method to remove all subviews from cell:
override func prepareForReuse() {
for views in self.subviews {
views.removeFromSuperview()
}
}
But I have created UITableViewCell subclass and declared this method in it.
you can also do one thing as #sCha has suggested. Add tags to the subviews and then use the same method to remove subview from cell:
override func prepareForReuse() {
for view in self.subviews {
if view.tag == 1 {
view.removeFromSuperview()
}
}
}
Hope this helps.
I think the other answers already mentioned a solution. You should subclass the tableview cell and just change the values of your layout elements for each row.
But I want to explain why you get this strange behaviour.
When you call
tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
it tries to reuse an already created cell with the passed identifier #"cell". This saves memory and optimises the performance. If not possible it creates a new one.
So now we got a cell with layout elements already in place and filled with your data. Your code then adds new elements on top of the old ones. Thats why your layout is messed up. And it only shows if you scroll, because the first cells got no previous cells to load.
When you subclass the cell try to create the layout only once on first initialisation. Now you can pass all values to the respective layout element and let the tableview do its thing.
Try this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil
{
cell = UITableViewCell.init(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
}
for subView in cell.subviews
{
subView.removeFromSuperview()
}
// Your Code here
return cell
}
I am using SDWebImage library to download image and load into image view inside a table cell.
I want to resize the table cell after the image is downloaded. Please advice. Many thanks.
Cell is not resize correctly after image set into image view
Cell resize correctly after dequeue and load again
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(GagListTableViewCell.cellId, forIndexPath: indexPath) as! GagListTableViewCell
cell.layoutMargins = UIEdgeInsetsZero
let gagDataCommand = gagDataSource[indexPath.row]
if let caption = gagDataCommand.caption {
cell.captionLabel.text = caption
}
if let imageUrlStr = gagDataCommand.images?.normal {
if let imageUrl = NSURL(string: imageUrlStr) {
cell.gagImage.sd_setImageWithURL(imageUrl, placeholderImage: UIImage(named: AppConstants.imagePlaceHolderName), completed: { (image, error, cacheType, url) in
//guess I need to redraw the layout here
})
} else {
//fail to get image url, set placeholder image to the cell instead
cell.gagImage.image = UIImage(named: AppConstants.imagePlaceHolderName)
}
}
return cell
}
You could use automatic dimension for tableview cell.
tableView.rowHeight = UITableViewAutomaticDimension
How to make the tableview cell that has been selected to no color as Vine App.
I've tried it but with clear color but the cell white out when it is get selected
Vine example no background color change
https://vid.me/tfkk
My project : Cell color changed even if it was set to clearColor
https://vid.me/awCq
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! DiscvoerTVC
let colorView = UIView()
colorView.backgroundColor = nil
UITableViewCell.appearance().selectedBackgroundView = colorView
if indexPath.row == 0 {
cell.DiscoverViewColor.backgroundColor = UIColor.grayColor()
cell.DiscoverViewLabel.text = "USMLE CK"
cell.backgroundColor = UIColor.grayColor()
cell.layer.cornerRadius = 20.0
cell.layer.masksToBounds = true
let colorView = UIView()
colorView.backgroundColor = nil
UITableViewCell.appearance().selectedBackgroundView = colorView
}
You mean cell's selection style? If so, set its selection style to none
cell.selectionStyle = .None;
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("NewsCell", forIndexPath: indexPath) as! UITableViewCell
cell.imageView?.image = nil
let imgURL = NSURL(string: urlString)
cell.imageView?.image = UIImage(named: "first")
// cell.imageView?.image?.drawInRect(CGRectMake(0,0,50,50))
// or
// cell.imageView?.frame = CGRectMake(0,0,50,50)
// also tried this
cell.imageView?.image = UIImage(named: "first")
cell.imageView?.contentMode = .ScaleAspectFill
cell.imageView?.clipsToBounds = true
Neither seems to make a difference.
When the image loads from the URL online it takes its original size.
I have omitted the code used for asynchronous image downloading because I figure its the same problem here. If not let me know. Thanks !
You should set Mode property of your UIImageView into Aspect Fit where you are showing the image at your cell.
You need to set the contentmode of the imageView either in code or in Interface Builder, and then once you do that you need to usecell.imageView?.clipsToBounds = true