UICollectionView inside UICollectionViewCell - ios

I'm struggling to find a way do something like this:
I'm using mostly UICollectionView to make my custom lists. And this time I want to add another UICollectionView inside a UICollectionViewCell.
The Layout is formed by a list of card, containing the informations below and inside it a list of items that came inside the same array.
Any ideias of how should I do this?
P.S: I'm not concerned about performance or something like this. So any idea would be welcome.

For your case I see some solutions:
Use only one UICollectionView and reuse needed cells for correct layout;
Use 'UICollectionView' inside UICollectionViewCell. You need to add another collection view as subview in one of your cells;
Configure subviews in your UICollectionViewCell as you want to showing needed content correct.
In my opinion you can choose first or last method, based on layout of your content and possibly dynamic height (if it's needed in your app).

I managed to do this in another way. Instead of embed a UICollectionView inside another, I iterated through the array of elements and created subviews above the label.
if let item = info["PRODUTOSITENS"] as? [[String:Any]] {
for produto in item {
// All the business logic
let DynamicView = UIView(frame: CGRect(x:Double(cell.status.frame.origin.x), y:y, width:Double(collectionView.frame.size.width - 20.0), height:80.0))
cell.addSubview(DynamicView)
}
}

Related

Reusing cells with dynamic layout content at runtime

I have a type of UITableViewCell that lets the user add/remove as many UITextViews as they want at run time.
I'm running into issues when trying to reuse/dequeue cells of that type, as sometimes the tableview cells just start overlapping when you scroll up and down. When I dequeue/return the cell, I'm running a setup method (which initiates a teardown method internally first to remove all the previous views), and uses the model to setup/restore all the necessary views and layout constraints.
if let cell = tableView.dequeueReusableCell(withIdentifier: "MultipleContentCell", for: indexPath) as? MultipleChoiceTableViewCell {
cell.setupCellWithModel(model: model)
cell.setNeedsUpdateConstraints()
cell.updateConstraintsIfNeeded()
cell.delegate = self
return cell
}
I can't really figure out why that cells sometimes overlap in the tableview, but I'm guessing it has to do with the layout being recreated on the fly. I'm considering not reusing these types of cells and just storing them in a list.
My question is: are reusable cells always suppose to have the same general UIView layout, and only the content changes? Am I not supposed to use reuse these types of cells? Or has someone experienced this before?
Thanks
The UITextView are created each time you dequeue cell and never delete. To repair that use function prepareForReuse(). You have to define, what your cell should do before dequeue in MultipleChoiceTableViewCell. For example:
override func prepareForReuse() {
super.prepareForReuse()
for view in speciesName.subviews {
if view is UITableView {
view.removeFromSuperview()
}
}
}
I added similar question few days ago:
Cells in UITableView overlapping. Many cells in one place
If you have some question, I can try to help you more tomorrow.
Cheers!
In general, yes. You want the physical layout of your cells to be static, and only vary the contents when you recycle them. If you add views to your cells in cellForRow(at:) then the burden is on you to manage the extra fields to avoid duplicate views.
Your case where you add a variable number of views to a table view cell based on user interaction is an odd case where you might need to add and remove cells on the fly.
One way to handle this would be to put all of your text fields in a container view, add an outlet to that container view, and then simply use code like this in your prepareForReuse or cellForRowAt function:
containerView.subviews.forEach { $0.removeFromSuperview() }

adding subview in a single uitableviewcell

Im facing a problem with adding a UIImageView to a single UITableViewCell. I add the subview like this in the cellForIndexPath delegate method which is ONLY added to the cell if the self.mediaTypeArray contains the string: "Image" at the index: indexPath.row
let cell = self.timelineTableView.dequeueReusableCellWithIdentifier( NSStringFromClass(ClassicCaseCell), forIndexPath: indexPath) as? ClassicCaseCell
if self.mediaTypeArray[indexPath.row] == "Image" {
let imageView = UIImageView()
imageView.frame.size = (cell?.evidenceView.frame.size)!
imageView.frame.origin = CGPointZero
imageView.image = img
cell?.evidenceView.addSubview(imageView)
}
Which it works great however, I find that every other two cells contains that same imageView even when self.mediaTypeArray[indexPath.row] is NOT equal to "Image" and I don't understand why. I think it may have something to do with reusable tableviewcells but I still don't see why it would do this. Please help!
I'm getting the feeling that this is because of cells being re-used.
A way you can work around this is to override your ClassicCaseCell's prepareForReuse method to remove any image view from its evidenceView.
I would however recommend that you don't add the image view in this fashion (through the delegate's cellForIndexPath method). Instead, your ClassicCaseCell should hold the image view as an instance variable which you can then set in cellForIndexPath. This way, there is only at most one. You can also make sure to set the image view to be nil in prepareForReuse, making sure that it won't appear in the cell if it is not set.
First, don't use tag property as recommended elsewhere. That was a technique used a long time ago, but Apple discourages that practice now. Second, I'd suggest you simplify your life and simply don't programmatically add image views in cellForRowAtIndexPath. If you programmatically add image views, cell reuse introduces a clumsy process of determining whether (a) you need an image view; (b) whether there is an existing image view; and (c) possibly adding/removing image view and/or getting reference to existing one.
One very simple solution is to just have two cell prototypes, one with an image view and another without. Then, based upon the media type, dequeue a cell with the appropriate storyboard identifier and use it.
The other alternative is to have the image view in the cell regardless, and hide/show it as appropriate. The challenge then becomes how to best manage two sets of the constraints, one for when the image view is visible and one when it's not. You can do this with judicious choice of constraint priorities, activating/deactivating the appropriate constraints in cellForRowAtIndexPath, etc. It can be done, but this is more cumbersome than the above approach, whereby you just employ two cell prototypes.
You only need to add the UIImageView once so if the cell is re-used again, it (might) already be there. Your problem is to detect if you've already added it or not. Here are a couple suggestions:
1) ALWAYS create it (and just don't set the image, or hide it)
2) assign it a unique tag and look for the tag when you need to set it... no tag, then create it
Override prepareForReuse delegation in your tableview cell and remove imageview from there

Access child views in custom UITableViewCell

Background:
I am trying to create a table view with around 4 types of different cell layout.
At first, I considered using static table view to solve the issue since the number of rows are somewhat fixed (nor more than 10)
But, after some thinking, I decided that I don't really want to be tied up to the UITableViewController. Thus, I tried to implement it with dynamic table view.
Question:
After I create 4 prototype cells, I found out that I'll need to access the child views in cell (to update their value). But the only possible ways I know seem to be:
1. Create a subclass for each prototype cell, and create `IBOutlet` to the child views
2. Assign `tag` for each child view for later access
But I don't really like these two methods...
The first one is too cumbersome, and the tag in the 2nd solution does't seem to be very sepcific (access the child view by just some magic number..)
So, I would like to know:
Is there any better practice for implementing this kind of
tableview. (multiple cell prototypes, and fixed row numbers)
Is static table view a better way to do it? If yes, will there be
any limitations when I am tied up to UITableViewController?
For example, if I need more complex UI, and decide to add more views on to it, will UITableViewController be less flexible than UIViewController
Thank you so much!
If the cells are very similar but with different layouts they could share a common UITableViewCell subclass provided the class doesn't need to know the layout it is in just configure the available outlets.
If the code does need to be aware of the layout used then it is probably best to make them separate subclasses.
For Swift use is or as? to confirm the correct subclass for the cell (for Objective C it would be the isKindOfClass method).
1.You do need to subclass the UITableViewCell if you want to access his IBOutlets.
In order to distinguish between the cell just use isKindOfClass
2.It depends how different your cell are from one another. If they have slightly different structure you might want to consider lodging the elements in cellForRow. Try to take a look at the built in structure cause it might save you some subclassing.
These structures have built in parameters such as: image,text etc.
Their structure is more strict though
Theses are the available types:
UITableViewCellStyleDefault, // Simple cell with text label and optional image view (behavior of UITableViewCell in iPhoneOS 2.x)
UITableViewCellStyleValue1, // Left aligned label on left and right aligned label on right with blue text (Used in Settings)
UITableViewCellStyleValue2, // Right aligned label on left with blue text and left aligned label on right (Used in Phone/Contacts)
UITableViewCellStyleSubtitle // Left aligned label on top and left aligned label on bottom with gray text (Used in iPod).
I don't really understand why you want to use tags?

Placing an UImageView inside ? or outside ? a UITableView

I'm trying to display an image with a tableView like so (see image below).
But I'm not sure about the way to implement the red part :
is the red part in the header part of the table view ?
is the red part outside of the table view ?
is this in a custom cell ?
PS : Note that the tableView I would like to be with the picture would have various sections.
Thank you very much for the help.
In this case it's either a header or a custom UITableViewCell because it scrolls with the table. You can implement it either way.
Personally I'd start by making it a cell. That will allow you to use autolayout to easily tackle sizing and dynamic type.
create a custom view as per suthar's comment and add it to the tableview headerview ,
if you have more than one sections than u can use the groupped tableview instead of plain tableview...it becomes more easy..

UITableViewCell next to eachother

How can i make a tableview where the cells are next to each other. Where there are 2 on each row. example like this? In the second row there are 2 images next to each other. Can this be done in a tableview by making custom tablevieCells?
Yes this can be done in UItableViewCell But preferred to use collection view for this kind of view.
Just subclass uitableviewcell, add new method
-(void)setCellWithNumberOfImages:(NSInteger)images withImage1:(UIimage *)image1 withImage2:(UIImage *)image2;
if(image2 ==nil)
//add only one UIimageView with image1
else
//add two imageviews.
You need to use a UICollectionViewController (https://developer.apple.com/library/ios/documentation/uikit/reference/UICollectionViewController_clas/Reference/Reference.html)
Using a UICollectionView you can implement a custom layout which layouts the elements as in your screenshot
You can Use UICOllectionView That's much easier and customizable, you can chose how many item you want to have in a row and size for example.
for more information please check: UICollectionView Class Reference

Resources