AutoLayout for UICollectionView Cells - objective-c

I have an uicollectionview in my app which shows the photos from the camera roll (using AssetsLibrary) in small square cells by using an uiimageview. My problem is that it all looks fine on an iPhone5/5S but there is huge spacing between the cells when running it on an iPhone 6. The question is: How could I make the cells resize themselves so that the spacing stays the same on all devices? (And the cells grow instead).

After set auto layout for UIImageView to make sure that UIImageView will fit to cell and make the adjustments to the cell size from there
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
int cellWidth = (SCREEN_WIDTH - (3 * PADDING)) / 4;
return CGSizeMake(cellWidth, cellWidth);
}

Make your collection view controller follow the protocol of UICollectionViewDelegateFlowLayout and override the following method. Then you can size your cells based on the size of your view's bounds.
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
// Calculate size based on your view's bounds here
}
Note: If you're also dealing with rotation you'll have to invalidate your collection view layout when the device rotates in order for this method to be called again and recalculate the sizes.
[self.collectionViewLayout invalidateLayout];

Related

collectionview inside tableview on expand collapse with dynamic cell height. objective c

i need when i expand-collpase tableview indide tableviewcell i opened collectionview, also i need dynamic height of collectionview according to its item.also tableviewcell height dynamic. currently i am statically chaing height based on expand collpase.I need similar to this image
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (self.selectedIndex == indexPath.row) {
return 150;
}else{
return 40;
}
}
tableview method for adjusting row height, i want it to be dynamically set height. also i have collectionview inside it. for reference i have 2 images it working fine but with static heigt i want it dynamically.[following is the image for reference][2]
[1]: https://i.stack.imgur.com/iJ8Df.png
image when collectionview item is more set, i want it to set dynamically
First,get the cell's model,then calculate with image count,for example:
// cell height is 40
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return model.images.count / 6 * 40
}

How to use Autolayout and self-sizing cells in iOS8

I have setup the auto-sizing cells with UILabels with no problem in iOS8 following this tutorial:
http://useyourloaf.com/blog/2014/08/07/self-sizing-table-view-cells.html
But I am having problems setting up a UIImageView using auto-sizing. I need the images to be different sizes in Landscape compared to portrait (so they retain the same aspect ratio). But each time I get a broken layout constraints error
"<NSLayoutConstraint:0x14554680 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x14564440(200)]>
As the actual code has quite a few different types of cell (that all work with auto-sizing cells) I have setup a simple example of the issue with a blue image view here:
https://github.com/AdrianMW/ios8autosizingCells
I have setup the constraints to the superview and am setting up the height like so:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kImageCell forIndexPath:indexPath];
cell.heightConstraint.constant = [self heightForOrientation:self.interfaceOrientation];
return cell;
}
Solutions Tried
I have tried turning off setTranslatesAutosizingMask: on the cell as per some of the other suggestions but when I do I just get a blank space instead of a image. I have also tried adding the following:
[cell setNeedsDisplay];
[cell layoutIfNeeded];
I have seen mention of overriding sizethatfits: to get it to work on this cell using the old way but that doesn't seem to be called on the cell.
Cheers
In your ImageTableViewCell.xib, try changing the constraint:
Image View.Bottom EQUAL Superview.Bottom
Change the priority from 1000 to 999.

Have access to UITableViewCell from heightForRow

I have the following code:
- (CGFloat)tableView:(UITableView *)_tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
return cell.imageView.frame.size.height + 40;
}
What I want to do is be able to access the cell's properties somehow. I want the cell's height to be equal to the height of the image in the cell's image view. I don't think this is working.
Don't try to access the cell. Your table's data source or some other object besides your cell should be managing that image. Ask that object for the image and take its size.
Treating your cell as a data container is tangling up your model, view, and controller layers and is likely to make changes more difficult down the line.

Resize UICollectionView cells after their data has been set

My UICollectionView cells contain UILabels with multiline text. I don't know the height of the cells until the text has been set on the label.
-(CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
This was the initial method I looked at to size the cells. However, this is called BEFORE the cells are created out of the storyboard.
Is there a way to layout the collection and size the cells AFTER they have been rendered, and I know the actual size of the cell?
I think your are looking for the invalidateLayout method you can call on the .collectionViewLayout property of your UICollectionView. This method regenerates your layout, which in your case means also calling -collectionView: layout: sizeForItemAtIndexPath:, which is the right place to reflect your desired item size. Jirune points the right direction on how to calculate them.
An example for the usage of invalidateLayout can be found here. Also consult the UICollectionViewLayout documentation on that method:
Invalidates the current layout and triggers a layout update.
Discussion:
You can call this method at any time to update the layout information. This method invalidates the layout of the collection view itself and returns right away. Thus, you can call this method multiple times from the same block of code without triggering multiple layout updates. The actual layout update occurs during the next view layout update cycle.
Edit:
For storyboard collection view which contains auto layout constraints, you need to override viewDidLayoutSubviews method of UIViewController and call invalidateLayout collection view layout in this method.
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[yourCollectionView.collectionViewLayout invalidateLayout];
}
subclass UICollectionViewCell and override layoutSubviews like this
hereby you will anchor cell leading and trailing edge to collectionView
override func layoutSubviews() {
super.layoutSubviews()
self.frame = CGRectMake(0, self.frame.origin.y, self.superview!.frame.size.width, self.frame.size.height)
}
Hey in the above delegate method itself, you can calculate the UILabel size using the below tricky way and return the UICollectionViewCell size based on that calculation.
// Calculate the expected size based on the font and
// linebreak mode of your label
CGSize maximumLabelSize = CGSizeMake(9999,9999);
CGSize expectedLabelSize =
[[self.dataSource objectAtIndex:indexPath.item]
sizeWithFont:[UIFont fontWithName:#"Arial" size:18.0f]
constrainedToSize:maximumLabelSize
lineBreakMode:NSLineBreakByWordWrapping];
- (void)viewDidLoad {
self.collectionView.prefetchingEnabled = NO;
}
In iOS 10, prefetchingEnabled is YES by default. When YES, the collection view requests cells in advance of when they will be displayed. It leads to crash in iOS 10

UITableViewCell Align all subviews

I have a custom UITableViewCell which has some subviews. i.e. some labels, some images. I want all these subviews to be right aligned in the UITable. How do i do that?
I have tried these approaches -
1.In InterfaceBuilder when I select the UITableViewCell, I can set the "indentaion" section. It's by default 0, I made it 100 but I see no change in the device.
2.I have tried this in the code too. Override the default method...
(NSInteger)tableView:(UITableView *)tableView
indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 100;
}
The above code also does not work. How do I align all my subviews in my UITableViewCell to right?
Basically, I want to display one cell left aligned (which is default) & some cells right aligned. As shown in the picture.
There is automatic way everything will align to right. You will have to lay the view appropriately. For UITextField and UILabel objects you can set the textAlignment property to UITextAlignmentRight.
label.textAlignment = UITextAlignmentRight;
If necessary you must also adjust the autoresizingMask of the views to set it such that it has a UIViewAutoresizingFlexibleLeftMargin mask set so that they stick to the right on view resize.
use interface builder for alignment.