Expand a UICollectionView in the middle of rows - ios

I have a UICollectionView like following:
Is it possible to add scrollable content in the middle of rows on click of a cell like following:
If yes, then how?

You can use this sample to your own need.
Expandable UICollectionView

What you can do is create 2 custom UICollectionView layouts. One without spacing and another one with it. Then animate change of the layout using method:
setCollectionViewLayout:animated:completion:

I'm going to have to assume you're using UICollectionViewFlowLayout for this purpose.
What you can simply do is add a new Cell at the desired indexPath and in the sizeForItemAtIndexPath datasource method, return the desired size (full width, required height). The flow layout will handle the rest for you.
Inside that cell, you can use a UIScrollView to get the Scrollable Content.
Update
Your cellForItemAtIndexPath:(NSIndexPath *)indexPath will look something like this
if(indexPath.item == myItemIndex && indexPath.section == myItemSection)
{
return CGSizeMake(768,200);
}
else
{
return CGSizeMake(128,128);
}
The values above are just examples. Modify them to suit your needs.

Related

How to delete specific views from TableView cell and get back those views in next cell?

I have a TableView with a custom cell. The cell is having multiple views and labels inside it. Now based on conditions I want to remove views and labels from the cell but in next cell I want them back and remove different set of views and label.
As I am using dequeueReusableCellWithIdentifier so after deleting the views from first cell I am not getting those views in second cell.
I don't want to hide them as I need some auto layout adjustment.
How can I do this?
Use prepareForReuse() in UITableViewCell:
override func prepareForReuse() {
super.prepareForReuse()
// add that view back
}
In custom cell you just add all view and label according to your requirement. In
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
}
you just hide or show view and label according to your need.
You can set a height constraint for the labels and views that you want to delete and set IBOutlets for the same, and instead of deleting the view from custom cell you could set the height constraint to 0 as per your condition. So the views and labels wont appear in the screen. Hope this will Help you. :)

How do I tell my UITableViewCell to "auto-resize" when its content changes?

In my cell.xib, I have a label, with constraints to all its sides. I've set that label to lines = 0 and line-break = word wrap. Then, I do this to my TableView:
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 100.0
Everything works great, and my UITableViewCell is auto-height. If the text is long, then my tableView intelligently calculates the size.
The problem is -- how do I tell my UITableView to "re-calculate" the size once the content changes in the cell?
My cell could call its delegate, and in this delegate, I'd like the TableView to re-draw the height.
Right now, the content in my cells change constantly, but the cell height never changes.
There is a documented way to do this. See UITableView.beginUpdates() documentation:
You can also use this method followed by the endUpdates method to animate the change in the row heights without reloading the cell.
So, the correct solution is:
tableView.beginUpdates()
tableView.endUpdates()
Also note that there is a feature that is not documented - you can add a completion handler for the update animation here, too:
tableView.beginUpdates()
CATransaction.setCompletionBlock {
// this will be called when the update animation ends
}
tableView.endUpdates()
However, tread lightly, it's not documented (but it works because UITableView uses a CATransaction for the animation).
I've found the best way to get it to check heights is to call, after whatever text change has been made, in order:
self.tableView.beginUpdates()
self.tableView.endUpdates()
This causes the tableView to check heights for all visible cells and it will cause changes to be made as needed.
I think the simplest solution is to reload that specific cell. For example:
- (void)yourDelegateMethodOfCell:(UITableViewCell *)cell {
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
//If cell is not visible then indexPath will be nil so,
if (indexPath) {
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
You can get automatic cell height by this code
tableView.beginUpdates()
// add label text update code here
// label.numberOfLines = label.numberOfLines == 0 ? 1 : 0
tableView.endUpdates()
Below is the reference to this solution with demo :
GitHub-RayFix-MultiLineDemo
I got your point, and I met the problem before.
Your cell is in AutoLayout, and you wish the cell changes by itself. Here is recommended answer for that: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights , so we don't talk about that again.
So here we focus on your problem.
Since the content of your cell changes constantly, which means the content has updated. Here we suppose the content is a label. We set the label's text, and surely the label's height maybe change.
Here comes the point: How does the label's change inform the cell to update?
We use AutoLayout, surely we have to update the constraint of height for the label.
And I think it will work!
Below is the detail step:
1. We setup the constraints for the cell's subviews.(I think it's done)
2. One of the label's height is changed by itself.(I think it's done too)
3. We get the new height of the label, and update the constraint of height for the label.(what we have to do)
Seems you wanted to reload the particular cell/cells based on content changes
Here we have a couple of options
1) Need to reload the entire table view .
or else
2) Reload particular cell/cells based on content changes.
But the preferred option would be reloading the particular cell,
Why because
when you asked your UITableView instance to reload a couple of cells,tableview will asks its datasource(-tableView:cellForRowAtIndexPath:) to get the updated content,so that the reloaded cells will have the updated size & Updated content aswell.
Try to reload the cells when the content/height need to update based on content
Hope that helps!
Happy coding :)
Take a look at this answer : Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
How to achieve dynamic cell size is described very thorough there.
As a suggestion for testing try adding setNeedsLayout to:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
or
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
To disable the annoying tableView animation:
UIView.setAnimationsEnabled(false)
tableView.beginUpdates()
// cell.titleLabel?.text = "title"
// cell.detailTextLabel?.text = "Very long text ..."
// cell.detailTextLabel?.numberOfLines = 0
tableView.endUpdates()
UIView.setAnimationsEnabled(true)
You can resize your cell height by implementing below method only
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;
}

Cell content not showing up if heightForRowAtIndexPath is implemented

I'm using iOS 9.2 and XCode 7.2.
I have a basic UITableView object in which i add different kind of UITableViewCell subclasses.
With one of them, when i set manually the height overriding the method heightForRowAtIndexPath, i don't get any content on the cell.
If i return -1 as height(the default value for the UITable row height), i get my cell showing up correctly. The thing is that i do need a different height for this row because the content is quite big.
here is the code for heightForRowAtIndexPath:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
MenuItem *menuItem = [menuManager menuItemAtIndex:indexPath.row];
if ([menuItem type] == MenuItemTypeEditorHeader) {
return 100;
} else {
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
MenuItem is a class containing the specific menu object' informations, such as the type. The result is that the cell is showed up at the correct height, but it's empty.
Its not advisable to use heightForRowAtIndexPath anymore - thats old-school. Instead, do this :
Set up autolayout constraints in your cell (if you dont know how to - you need to, its not something you can avoid anymore!)
Create an estimatedRowHeight for autolayout to use, on the tableView. You can set it in the nib/storyboard or programmatically, in viewDidLoad for eg, like this :
self.tableview.estimatedRowHeight = 68.0;
Set your tableview to use 'automatic dimension', like this :
self.tableview.rowHeight = UITableViewAutomaticDimension;
And thats it. If you do these things, then your cells will vary in height according to their constraints. So if one of your subclasses has a height of 150px due to its constraints, that will work perfectly next to another subclass that has a height of 50px. You can also vary the height of a cell dynamically depending on the contents of the cell, for eg when you have labels that expand using 'greater than or equal to' constraints. Also - simply omit the 'heightForRowAtIndexPath' method, you dont need to implement it at all.
Are you calling tableView.reloadData() ?
print the length of menu objects before you call tableView.reloadData().
HeightForRowAtIndexPath just returns height of a row. So may be problem in cellForRowAtIndexPath.

How to customize my UITableView cell as below

Am using custom tableview cell in my code. Please can anybody help me how to write the code for common friends cell. How can i get the names AMANDA,VIKA LEVINA,NATASHA,KATE,JESICA names in rectangular box.
For common friends and Facebook interest cells you can use UICollectionView and adjust cell width depends upon text otherwise you can use one of below listed controls.
https://www.cocoacontrols.com/controls/jctaglistview
https://www.cocoacontrols.com/controls/taglistview
https://www.cocoacontrols.com/controls/antagsview
you have to design two custom cells in your IB first for image view cell and other for list given below in your cell. create two custom cell in IB and design them according to your need and after that in your cell for row at index path method differentiate between these cell like:
uitablviewCell *cell;
if(indexPath.row == 0)
{
cell = [tableview dequereusablecellWithIdentifier:Firstcell];
}
else
{
cell = [tableview dequereusablecellWithIdentifier:secondCell];
}
For common friends and Facebook interest cells, You can use ANTagsView.
Using this, You can get tag view which you are showing in image.
So this view, you can add into your cell. For tags view, you have to pass array according to your view.
And set height of cell dynamically using heightForRowAtIndexPath method.
After that, you can get your view.

How to create customized UICollectionView with 2 or more custom cells?

in my project I want to use UICollectionView with custom cells, I created collection view with custom cells but I want to use Different size of custom cell in my project I followed some tutorials but I din`t get it properly, and below I attached sample screen shot of what i really looking for collection view.
One of the possible ways to create this is to use sizeForItemAtIndexPath and then return the size for your Cell. Here are some useful links on Github which are exactly doing what you want :
RF Quilt Layout
Mosaic Layout
As in the First image, some cells have buttons whereas others don't have. For this, you will have to create custom Cells i.e one custom cell with buttons and one without buttons. And inside your cellForItemAtIndexPath function, you can define them with some if-else condition.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if(firstCellConditionMet)
{
CustomCell1 *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"CellIdentifier" forIndexPath:indexPath];
//Your code
return cell;
}
else{
CustomCell2 *cell2 = [collectionView dequeueReusableCellWithReuseIdentifier:#"CellIdentifier2" forIndexPath:indexPath];
//Your Code
return cell2;
}
}
}
This can be achieved by Collection View Flow Layout. You can create a flow layout and that layout will take care of different rows and how many elements are there in a row. Have a look at Ray Wenderlich's Tutorial here.
if it is what you want
https://www.youtube.com/watch?v=LFBTbmvFR30
try to use custom layout for collection view
https://github.com/bryceredd/RFQuiltLayout
this is ready decision and it it is easy to use, If there are questions, will answer you,now i do the very similar collection...but on iPad with random cell size>>>>
and the most cool, with this realization you will be able to use one class for all cell sizes, if you use constraints. If you have problem with this realization, i can give you my test project.
Good luck bro.
I think it's very easy. You can subclass UICollectionViewFlowLayout.

Resources