Trouble Loading Images in UITableView - ios

I'm trying to put images into my UITableView. The Table is set up with a custom subclass cell. In the Subclass I have outlets:
#IBOutlet var titleLabel: UILabel!
`#IBOutlet var pillarIcon: UIImageView!`
In the Superclass I created a NSMutableArray for both:
var objects: NSMutableArray! = NSMutableArray()
var imageObjects: NSMutableArray! = NSMutableArray()
I place things into the Arrays within the viewDidLoad Method Each array has 4 items.
So when I call the Items:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.objects.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCell
cell.titleLabel.text = self.objects.objectAtIndex(indexPath.row) as? String
cell.pillarIcon.image = self.imageObjects.objectAtIndex(indexPath.row) as? UIImage
return cell
}
The cell.titleLabel.text items come up but the images in the cell.pillarIcon.image do not come show up in the table.
I have been working on this for a couple hours now and am going in circles it feels like. Also the image files have been loaded into the main file so that is not the problem.
Thanks in advance.

Make sure that your images are loaded into your Images.xcassets and then use the UIImage(name:) method to load the images.
Currently, you are loading your images into your imageObjects array as follows:
self.imageObjects.addObject("book.jpg")
You are not using the UIImage to load the image.
Once your images are a part of your project's image assets (Images.xcassets), load your images like so:
self.imageObjects.addObject(UIImage(named: "book"))
(The above example assumes that book is the name of the image asset group.)
Note, this Adding Image Assets web page has instructions on how to set up an image asset group.

It seems like you are loading images incorrectly, like #whyceewhite said in his answer.
I will try to make it clear to you:
open Assets.xcassets
Drop all images you want to use under AppIcon
Add images to your array this way:
imageObjects.addObject(UIImage(named: "whiteboardapp")!)
Use the same name displayed on Assets.xcassets folder

Related

How do I use placeholder API on UIElements correctly

I'm implementing an API called Skeleton View on my Xcode Project. Sometimes when the app loads for the first time, it takes a little bit longer to load the UI Elements, because the data come from JSON and if the user is using 4G or even a bad internet, will remain an empty field. In additional, using this API it shows like a gray view animated placeholder on each UIElement that doesn't received data.
However, I don't know how to check when the UIImage received a value to be able to remove the Skeleton effect and present the Image. I'll post some pictures below.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! TableViewCell
let model = arrCerveja[indexPath.row]
cell.labelName.text = model.name
cell.labelDetail.text = "Teor alcoĆ³lico: \(model.abv)"
let resource = ImageResource(downloadURL: URL(string: "\(model.image_url)")!, cacheKey: model.image_url)
if cell.imageViewCell.image != nil {
cell.imageViewCell.kf.setImage(with: resource)
cell.imageViewCell.hideSkeleton()
}else{
cell.imageViewCell.showAnimatedGradientSkeleton()
//The placeholder still there even when the images already got downloaded
//What I wanted was, while the UIImageView has no value, the placeholder
//persists, but when receive the image the placeholder should be dismissed.
}
return cell
}
That's what I got on UIImages(it has a blur animation passing by):
The problem I'm facing is how do I dismiss this effect after each image load itself?
You will need to start the animation when starting the download (often just before your function that get the data) with:
view.startSkeletonAnimation()
The view property here is the one of your view controller, SkeletonView is recursive and will animate all views inside it.
And then after the download is completed (often in a closure before you reload your table view and I assume that all your images are downloaded and ready to be displayed) stop the animation with:
self.view.stopSkeletonAnimation()
Skeleton view also provide you a delegate for UITableView:
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
}
As the documentation says (read the part about Collections to understand how it works):
This protocol inherits from UITableViewDataSource, so you can replace this protocol with the skeleton protocol.
You will need to make your tableView skeletonnable in you viewDidLoad() function:
tableView.isSkeletonable = true

Create folders in UITableView from saved images

I have an iOS Xcode 7 project written in Swift2. I'm saving photos to the app using NSCoding:
class UserImages: NSObject, NSCoding {
// MARK: Properties
var name: String
var photo: NSData // UIImage
...
}
These images currently are shown in a UITableView:
class ImagesTableViewController: UIViewController, UITableViewDelegate {
// MARK: Properties
var photos = [UserImages]()
...
// MARK: TableView Details
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return photos.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "ImageTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! ImageTableViewCell
let photo = photos[indexPath.row]
var image: NSData = photo.photo as NSData
cell.nameLabel.text = photo.name
cell.photoImageView.image = UIImage(data: image)
return cell
}
}
Works great, and in my custom cell, I have a UILabel and UIImageView for the name and photo.
My question is, how can I allow the user to create folders within the UITableView and allow the photos to be moved/organized in the folders? I'd like to try and keep the NSCoding unless it's impossible to implement folders and still use NSCoding. Thank you.
I ended up not using NSCoding and instead saving everything with CoreData. I setup an Entity called Photos and gave it attributes of:
name // Set as String
imageData // Set as Binary Data
folder // Set as String
The user then can add a new image and set the name of the photo and folder they want to put it in using UITextFields.
I then setup a FolderTableViewController displaying the folders from a request and in the didSelectRowAtIndexPath captured the image name from the selected cell and transferred it to a new ViewController which has a UITableView and displays the images from FolderTableViewController performing a request.predicate.
Works well for what I needed it to do. May not be the most glamorous but it made sense and did what I needed it to.

UIImageView Array not showing contents?

I have an array of UIImageViews that I want to display to the screen. However, I can't seem to be able to do so. I declared my array of UIImageViews like so:
class EventCell: UITableViewCell, CellDelegate{
#IBOutlet var eventName: UILabel!
#IBOutlet var eventLocation: UILabel!
#IBOutlet var attendeesImages: [UIImageView]!
}
And I have a function that displays the EventCell contents like so:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//Dequeue a "reusable" cell
let cell = tableView.dequeueReusableCellWithIdentifier(eventCellIdentifier) as! EventCell
setCellContents(cell, indexPath: indexPath)
return cell
}
//Set contents of Event Cell.. self.events is a global array
//which have information that EventCell objects need to display
func setCellContents(cell:EventCell, indexPath: NSIndexPath!){
let item = self.events[indexPath.section]
var count = 0
cell.eventName.text = item.eventName()
cell.eventLocation.text = item.eventLocation()
cell.attendeesImage.removeAll(keepCapacity: false)//Remove old images before adding new
for value in item.attendeesImage {
let newImageView = UIImageView(image : value)
newImageView.clipsToBounds = true
newImageView.layer.cornerRadius = newImageView.frame.size.width / 2
cell.attendeesImage.append(newImageView)
println("Count inside: \(cell.attendeesImage.count)")
}
}
I printed out the count of the cell.attendeesImage to ensure that no extraneous images were being added and it seemed to prove correct. However, I have no idea why my images are not displaying. I made sure to hook the cell.attendeesImage as an IBCollection in my Storyboard (since it is an Array) in my EventCell. Any ideas for why this isn't showing up? Thanks!
You are using wrong the collection outlet "attendeesImages".
When the view is loaded, the array attendeesImages are created and initialized with the image views you have created in interface builder. But then, if you remove all that references, you have lost the link between the outlets and the real views. The new image views you are creating are not the ones in the cell. They are still subviews of the cell, but now you have not a iboutlet references to them.
The solution: don't remove the values from the array. Just modify the image in each image view.

IOS - SWIFT - CollectionView With images, loading URLs from array

I have a collection view and array with URLs of different images. and when i launch the app, collection view starts to load images through the array:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CellView
var url = arr[indexPath.row]
var urls = NSURL(string: url)
var data = NSData(contentsOfURL: urls!)
cell.ImageView.image = UIImage(data: data!)
return cell
}
and the trouble appearse:
for example on 4th cell collection view loading all 4 urls for all 4 cells and it takest alot time. how can collection view load particular url for particular cell and don't spend time to load urls to cells that already loaded?
Thanks for any help!!
I suggest using a third party library for this matter, it called SDWebImage.
And than for each image view inside a cell set:
self.imageView.sd_setImageWithURL(url, completed: block)
Or you can use similar third party library, as Asaf, told you. I used to use HANEKE for DL/cache images.
Take a look: https://github.com/Haneke/HanekeSwift
:)

PFImage in table view too large

I'm using Parse. I have a column in my table to store images as PFFiles. I am using a PFQueryTableViewController. I want to display images in my Parse table's "image" column as thumbnails for each table view cell that has an image associated with it.
Here is the relevant cellForRowAtIndexPath code I'm suspicious of:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!, object: PFObject!) -> PFTableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("ListingCell", forIndexPath: indexPath) as PFTableViewCell
// This works as you can see "grapes" displayed on the screenshot I added.
var label = cell.viewWithTag(2) as UILabel
label.text = object["title"] as? String
// Accessing the PFImageView within my custom PFTableViewCell via a tag
let imageView = cell.viewWithTag(3) as PFImageView
// Extracting the image stored as a PFFile stored in the database
imageView.file = object["image"] as? PFFile // remote image
// Setting the actual thumbnail with the image when loaded
imageView.loadInBackground { (image: UIImage!, error: NSError!) -> Void in
imageView.image = image
}
return cell
}
I have 2 records stored in this Parse table, the first does not have an image and the second one does (hence why the "grapes" cell is empty). My question is, why is the image not displaying in the thumbnail (properly constrained) I created and rather taking up the entire screen? What am I doing wrong here? The even weirder part is that I used Xcode's view debugging to capture the view hierarchy and it shows it properly placed within the thumbnail. Any ideas?
You need to make sure your image mode is set to something like "Scale To Fill".

Resources