Custom UICollectionView in Swift 3 not working - ios

So I am new to swift and am trying to create a custom UiCollectionView that you can horizontally scroll through, and when tapping on a button, you can add an image from your camera roll to the array of images in the collection view. This is what I have so far and I have run into some problems. I have tried watching videos online but I still get errors so i don't know what I am doing wrong. I have some images of apple products that I loaded into my assets folder and I will be using those images in an array for the collectionView. Each image will be in one colletionViewCell.
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var collectionView: UICollectionView!
let imageArray = [UIImage(named: "appleWatch" ), UIImage(named: "iPhone"), UIImage(named: "iPad" ), UIImage(named: "iPod" ), UIImage(named: "macBook")]
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.imageArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! UICollectionViewCell
cell.ourImage?.image = self.imageArray[indexPath.row]
return cell
}
}
It gives me an error here cell.ourImage?.image = self.imageArray[indexPath.row] and says that "value type UICollectionViewCell has no member 'ourImage'" Even though I named the outlet ourImage on another UICollectionViewCell swift file. I have checked the Main.storyboard and I think I have named all of my classes correctly and have assigned them to the collectionViewCell and the identifier. I delete this line and it compiles fine, but whenever the app is run nothing shows up on the screen so there may be something wrong with my images too. Does anybody have any ideas? How would you go about creating a custom UiCollection View? Do I have the right idea?

Instead of casting the dequeued cell to UICollectionViewCell, you need to treat it as your custom UICollectionViewCell subclass.
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourReuseIdentifier", for: indexPath) as? YourCustomCollectionViewCell {
// set the cell's custom properties
}
You can also force cast using as! YourCustomCollectionViewCell, but I personally prefer not to do this.

Related

UIcollectionView weird cell recycling behaviour

I have a UICollectionView with flow layout, about 140 cells each with a simple UITextView. When a cell is recycled, I pop the textView onto a cache and reuse it later on a new cell. All works well until I reach the bottom and scroll back up. At that point I can see that the CollectionView vends cell number 85, but then before cell 85 is displayed it recycles it again for cell 87 so I now lose the content of the cell I had just prepared.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FormCell", for: indexPath) as! FormCollectionViewCell
let textView = Cache.vendTextView()
textView.text = "\(indexPath.row)"
cell.addSubview(textView)
cell.textView = textView
return cell
}
And on the UIcollectionViewCelC
override func prepareForReuse() {
super.prepareForRuse()
self.textView.removeFromSuperView()
Cache.returnView(self.textView)
}
I would have thought that after cellForItemAtIndexPath() was called, it would then be removed from the reusable pool of cells but it seems it is immediately being recycled again for a neighbouring cell. maybe a bug or I am possibly misunderstanding the normal behaviour of UICollectionView?
As I understand it, what you're trying to do is just keep track of cell content - save it when cell disappears and restore it when it comes back again. What you're doing can't work well for couple of reasons:
vendTextView and returnView don't take indexPath as parameter - your cache is storing something and fetching something, but you have no way of knowing you're storing/fetching it for a correct cell
There's no point in caching the whole text view - why not just cache the text?
Try something like that:
Have your FormCollectionViewCell just have the text view as subview, and modify your code like so:
class YourViewController : UIViewController, UICollectionViewDataSource, UICollectionViewDelegate
{
var texts = [IndexPath : String]()
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FormCell", for: indexPath)
if let formCell = cell as? FormCollectionViewCell {
cell.textView.text = texts[indexPath]
return cell
}
}
func collectionView(_ collectionView: UICollectionView,
didEndDisplaying cell: UICollectionViewCell,
forItemAt indexPath: IndexPath)
{
if let formCell = cell as? FormCollectionViewCell {
{
texts[indexPath] = formCell.textView.text
}
}
}

How to create collectionview in tableView Cell in swift 4? [duplicate]

This question already has answers here:
ios 8 Swift - TableView with embedded CollectionView
(3 answers)
Closed 4 years ago.
]2I have use one tableView. Inside tableViewCell i want to populate a collectionView.
I have a static array
Here is my code
var menuImage = ["download.jpeg","download (1).jpeg","download (2).jpeg","download (3).jpeg","download (4).jpeg","download (3).jpeg","download (4).jpeg","download (3).jpeg","download (4).jpeg"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menuImage.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:HomeTableViewCell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
// cell.collectionView.reloadData()
return cell
}
inside tableViewCell ->
class HomeTableViewCell: UITableViewCell {
#IBOutlet weak var collectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
and this is the collectionView
extension HomeVC: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return menuImage.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as! HomeCollectionViewCell
cell.imgvw.image = UIImage(named: menuImage[indexPath.row])
cell.profileName.text = menus[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Collection view at row \(collectionView.tag) selected index path \(indexPath)")
}
}
Still the static data is not showing. please help
If you want to show all images below username than you need to change the Layout. it's not possible in that layout.
so my suggestion is : You display only user details in HomeVC, once any row is tapped, move to new screen and show user details along with all images like instagram user profile.
Edit of your Demo : https://www.dropbox.com/s/v05k2udqa3pu1dd/Demp1.zip?dl=0
I would suggest you to Follow the steps mentioned in this Video Collection View inside TableView cell
Moreover you can refer this link also:
Collectionview in tableview cell
Hope this helps.
Issue in Image added
As stated by you , you have added the image directly to Xcode i.e. Drag and Drop,
So do cross check if the Target Member Ship is ticked or not.? If not the please tick that.
Also it is suggested to name the image properly like image1,image2,image3,image4,etc so that it gets detected without any issue.
Edit Link to a demo Project added
You can find a demo of Collection View inside a tableView cell here: Demo of imageCollectionView inside TableViewCell

In UICollectionView, the order changes automatically

I have a big problem.
I scrolled in the UICollectionView.
When the drawing area is scrolled too much, the arrangement order has become disjointed.
I do not want to change the order even though scrolling.
What should I do?
help me.
let titles = ["1","2","3","4","5","6","7","8", "9", "10", "11", "12"] //titles
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 12
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = testCollectionView.dequeueReusableCell(withReuseIdentifier: "TestCell", for: indexPath) as! TestCell //customCell
let testTitle = cell.contentView.viewWithTag(2) as! UILabel
testTitle.text = titles[indexPath.row]
return cell // yeah, all done. is these code is normal. right? But when i scroll this UICollection, change the order in Outside drawing area.
}
You should definitely not be using viewWithTag. The reason for this is because cells are dequeued, which means that cells that have been taken off screen by scrolling are reused for the cells which are about to come on screen. This is done to save memory. Sometimes the problem with the order can be because previously used cells are not updated quick enough when they are presented to the user. The solution to this if you are using a network request can be to firstly to streamline your request and then cache any heavy data that is returned, such as images.
Your code should not be causing the cells to change order. I'm wondering if you have a problem with using viewWithTag. That's a fairly fragile way to find views in a collection view/table view cell.
You already have a custom cell type. I would suggest creating an outlet to your label in your custom cell type, and referencing the label that way:
class TestCell: UICollectionViewCell {
//(Connect this outlet in your cell prototype in your Storyboard
#IBOutlet titleLabel: UILabel!
}
//And in your view controller's cellForItemAt method...
cell.titleLabel.text = titles[indexPath.row]

UICollectionViewCell with image without custom Class

there pretty simple Question actually:
I want a collectionView with an Image with the same size as the Cell. I want to do this all without building a extra class, so from storyboard (maybe, if I get on my subview?!)
And btw, i load data from web, so I Can't just add a new ImageView every time....
just wanna ask if this is possible?!
Cheers
If you have static Collection view then you can do without custom class
but you have dynamic Collection view then you need to create custom class.
which is look like this.
class AddAlbumCell: UICollectionViewCell {
#IBOutlet var imgv: UIImageView!
}
In your Collection view Delegate method
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! AddAlbumCell
cell.imgv.image = images[indexPath.row] //"images" contains image name array
return cell;
}

Collection View Cells not appearing in Collection View?

I created a Collection View using purely the storyboard interface builder. This is what the storyboard looks like:
My collection view's properties are default as well. I haven't written anything into my ViewController.swift yet.
For some reason, when I run on my phone / emulator, none of the buttons are showing.
UICollectionView does not support static cells like UITableView. You will have to set its dataSource,delegate and configure your cells in code.
Just configure the collectionView properly see below code and image:
Implement the delegate methods of collectionView:
class yourClassController: UICollectionViewDataSource, UICollectionViewDelegate {
override func numberOfSectionsInCollectionView(collectionView:
UICollectionView!) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView!,
numberOfItemsInSection section: Int) -> Int {
return yourArray.count
}
override func collectionView(collectionView: UICollectionView!,
cellForItemAtIndexPath indexPath: NSIndexPath!) ->
UICollectionViewCell! {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as CollectionViewCell
// Configure the cell
cell.backgroundColor = UIColor.blackColor()
cell.textLabel?.text = "\(indexPath.section):\(indexPath.row)"
cell.imageView?.image = UIImage(named: "circle")
return cell
}
Then from your storyboard set the delegate and datasource by drag and drop see image:
Note: collectionView appears when you do complete above formality with its relevant class.

Resources