Image overflowing bounds with clip to bounds set - swift

I have a UITableViewCell that has an image view within it:
Which has the following bounds for its large image:
And has the following setting:
The code around this is pretty simple, its using the KingFisher library to fetch the image:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let element = comments[indexPath.row]
...
tableView.register(UINib(nibName: "CommentImagePostCell", bundle: nil), forCellReuseIdentifier: "CommentImagePostCell")
if (element.Image != "" ){
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentImagePostCell", for: indexPath) as! CommentImagePostCell
let urlString = API.baseUploadURL + element.Image
let url = URL(string: urlString)
cell.imageView!.kf.setImage(with: url)
...
}
...
}
However the above code ends up with the image loading in an unclipped manner, seems to complete ignore the bounds? This works else where within my app so I don't think its something wrong with the library and just something I'm missing?
Anyone have any idea why its not clipping?

Common mistake:
UITableViewCell has its own imageView property and this is what you are currently setting the image to.
Replace:
cell.imageView?.kf.setImage(with: url)
With:
cell.imgView.kf.setImage(with: url)
Rename your UIImageView to something like imgView and update the code, as above, and you should be good.

Related

Loading an Image file from Firebase Storage using SDWebImage

I am trying to load an image from my Firebase Storage to be displayed on my app view.
I have 2 classes mainly
Main "ClassView" that includes a tableView.
A custom tableViewCell - "ClassCell" (This class includes an imageView where I want to display the picture from firestore. - imageView is called classImage.
Below is the tableView Data Source Extension.
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(UINib(nibName: K.tableCellNibName, bundle: nil), forCellReuseIdentifier: K.tableCellIdentifier)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let storageRef = storage.reference()
let reference = storageRef.child(K.FStore.classImagesPath)
let placeholderImage = UIImage(named: "placeholder.png")
let imageView: UIImageView = self.imageView
let cell = tableView.dequeueReusableCell(withIdentifier: K.tableCellIdentifier, for: indexPath) as! ClassCell
//below is where I try to set the my image but it is not changing anything
cell.classImage?.sd_setImage(with: reference, placeholderImage: placeholderImage)
//This I tried to make sure that I am can access the image right and it worked just fine
// cell.classImage?.backgroundColor = .black
return cell
}
The Image is not displayed using the sd_setImage method. Any help would be highly appreciated if I have any error in my code or missing a declaration anywhere.
Below is what I am getting when I run the simulator. Instead of the image displayed in these black boxes, they are empty. Also, the imageView.image is returning nil so most probably the sd_setImage is not placing the image right.
self.imgSidebarMenuImage.sd_imageIndicator = SDWebImageActivityIndicator.whiteLarge
self.imgSidebarMenuImage.sd_setImage(with: URL(string: (person["image"] as! String)), placeholderImage: UIImage(named: "logo"))
try this
#1
let storage = Storage.storage().reference(withPath: “YOUR_PATH”)
storage.downloadURL { (url, error) in
if error != nil {
print((error?.localizedDescription)!)
return
}
print(“Download success”)
//url = your will get an image URL
self.someImageURL = url!
}
#2
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// cell identifier methods
var item = itemData[indexPath.row]
let referenceImage: StorageReference = storageRef.child("YOUR_PATH")
let url = URL(string: referenceImage!)!
cell.itemImage?.sd_setImage(with: url, placeholderImage: #imageLiteral(resourceName: "placeholder"))
}
}
return cell
}

the data mix in table view, how do I avoid it? swift

I have some troubles, I have a table view with a custom cell, the cell has a image view, the image is downloaded from internet, when the data loaded the first time everything is fine, but if scroll quickly the screen, the images will mix.
this is my code
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell:FlinkerTableViewCell = tableView.dequeueReusableCell(withIdentifier: "flinkerCell") as! FlinkerTableViewCell
cell.imgeCell.image = nil
let row = indexPath.row
let flinkerAux: Flinker = flinkers[row]
if let stringURL = flinkerAux.image{
if stringURL != "" {
DispatchQueue.main.async {
cell.imgeCell.downloadedFrom(link: stringURL)
cell.imgeCell.contentMode = .scaleAspectFill
}
cell.imgeCell.setNeedsDisplay()
cell.lblTitle.text = flinkerAux.fullName
cell.lblSubtitle.text = flinkerAux.phone
}else{
cell.imgeCell.image = UIImage(named: "user_placeholder")
cell.lblTitle.text = flinkerAux.fullName
cell.lblSubtitle.text = flinkerAux.phone
}
}else{
cell.imgeCell.image = UIImage(named: "user_placeholder")
cell.lblTitle.text = flinkerAux.fullName
cell.lblSubtitle.text = flinkerAux.phone
}
cell.imgeCell.layer.cornerRadius = 20
cell.imgeCell?.clipsToBounds = true
cell.selectionStyle = .none
return cell
}
I'm using swift 4.2, I tried with DispathQueue load the images, but when the table view has so much images, the problem is back.
how I should do?
This is commonly known issue. I'm sure you can find a lot with google
The easiest option here is to use any library to download images, like AlamofireImage, Nuke, Kingfisher, SDWebImage
UITableViewCell asynchronously loading images issue - Swift

How to set Image at current Cell (Kingfisher)? Swift

I have an TableView with custom cells. Label smiles contain links.
How can I put Image from link to current ImageView'cell? My code
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "ClientCell"
self.cell = self.tableView.dequeueReusableCell(withIdentifier: identifier) as? customChatCell
let text = message[Constants.MessageFields.text] ?? ""
let selectedCell = self.tableView.cellForRow(at: indexPath) as? customChatCell
***
if text.range(of:"smiles") != nil {
let url = URL(string: text)
self.cell![indexPath.row].smile.kf.setImage(with: url)
}
***
}
not working. I'm getting error for line self.cell![indexPath.row].smile.kf.setImage(with: url)
Type 'customChatCell' has no subscript members
I'm using Kingfisher. If I use code
self.cell.smile.kf.setImage(with: url)
image putting into all cells, not for current.
Please help me fix it.
You should remove keeping the cell reference at class level. Your cellForRow should look like this,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "ClientCell"
let cell = tableView.dequeueReusableCell(withIdentifier: identifier) as? customChatCell
let text = message[Constants.MessageFields.text] ?? ""
if text.range(of:"smiles") != nil {
let url = URL(string: text)
cell.smile.kf.setImage(with: url)
} else {
// Reset image to nil here if it has no url
cell.smile.image = nil
}
}
Remember, you are using a single UIView(i.e, customChatCell) for each cell in UITableView so when you dequeue a cell it's your responsibility to update/reset the UI elements according to your data for each cell.

How to resize the imageView?

How do I resize the imageView?
Xcode says initialisation of imageView was never used.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
let city = nicosiaPlaces [indexPath.row]
cell?.textLabel?.text = city
let imageView = CGSize(width: 100, height: 100)
cell?.imageView?.image = UIImage(named: city)
return cell!
}
You just create a new CGSize every time when the method is called, you should change the size in your cell class instead. And if you're using storyboard with AutoLayout, you should change the size in storyboard.
I guess your question has some flaws inside.
Assuming that you need to resize an Imageview I'm posting small Snippet for you.
Never initialize any new component inside func tableView(cellForRowAt:IndexPath)
beacuse every time it is going to create a new Instance until they are properly disposed.
You have taken reference as let imageView = CGSize(--,--) but you are again calling the instance from Cell Method.
Don't do that.
override func awakeFromNib(){
let imageView = UIImageView(CGRectMake(0,0,150,150))
imageView.contentMode = .scaleAspectFill
contentView.addSubView(imageView)
}
Now In the Class method get reference of the ImageView and resize if you want.
overrride func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.deququeResuableCell(withIdentifier: "cellID",forIndexPath: indexPath) as! yourCustomCellClassName
cell.imageView?.image = UIImage(named: "yourImage")
// If you need to resize the Image make changes in Frame of Image or ContentMode of the Image.
return cell
}

Swift TableView making multiple network requests for images

I have a table in swift. Whenever I scroll up and down the tableview it runs the getImageForCell function again even though the image has already been loaded. Is there a way for this not to happen. Below is my code.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ReviewTableViewCell", for: indexPath) as! ReviewTableViewCell
let review = json[reviewType][indexPath.row]
cell.nameLabel.text = review[userType]["name"].stringValue
cell.reviewLabel.text = review["message"].stringValue
cell.dateLabel.text = review["created_at"].stringValue
cell.ratingStars.rating = Double(review["rating"].intValue)
getImageForCell(url: review[userType]["photo_url"].stringValue, cell: cell)
return cell
}
func getImageForCell(url: String, cell: ReviewTableViewCell) {
Alamofire.request(url).responseImage { response in
if let downloadedImage = response.result.value {
print("downloaded image \(downloadedImage)")
DispatchQueue.main.async {
cell.profileImageView.image = downloadedImage
}
}
}
}
This is due to both not cacheing the image, and also not reusing the cell - in your view you are recreating the cell each time - this would not specifically fix the image issue, but will improve performance. My favourite cache image extension is kingfisher (no affiliation), although alamofire can be used to cache images too.
https://github.com/onevcat/Kingfisher