UICollectionView with paging some content is off screen Objective-c - iphone

I've tried some solutions found on stackoverflow such as
self.collectionView.clipsToBounds = NO;
[self.scrollView setContentOffset:CGPointMake(0, 0)];
And nothing is working.
My collection view has a cell in it and should display one cell at a time. I'm using paging and evertyhing is working fine except that when you go to the second page it cuts a little of the cell off by the screen. And every page you go after that cuts more of the cell of till you get to the last page where half the cell is cut off. I'm doing this on iphone.

What is happening is, your cell is not centered, so as you swipe between them, and the UICollectionView dynamically figures out the spacing of each cell, it gradually becomes more and more off centre, getting the effect you explain.
Ensure that your UICollectionViewCell + UICollectionViewLayout insets equal the width of the contentView of your UICollectionView.
e.g.
On a 320.0f,100.0f UICollectionView. Your cell could be 300.0f,90.0f. And your UICollectionViewLayout (if using a flowLayout), could have the edge insets set to 5.0f,10.0f,5.0f,10.0f.
E.g.
[(UICollectionViewFlowLayout *)collectionView.collectionViewLayout setItemSize:CGSizeMake(320.0f, 100.0f)];
[(UICollectionViewFlowLayout*)collectionView.collectionViewLayout setSectionInset:UIEdgeInsetsMake(5.0f, 10.0f, 5.0f, 10.0f)];

It was min spacing for lines was on 10 so I set it to 0. I think thats a bug in xcode 5 because my collection view is scrolling horizontal not vertical so one would think it would be my min spacing for cells would be wrong

Please make each item in a section, NOT all items in one section.
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return [self.items count];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 1;
}
That's done.

Related

UICollectionViewCells with UICollectionViewFlowLayout - strange layout happening

I am currently testing in xcode a UICollectionView with just one horizontal row like a kinda cover flow. Basically I have my own Custom Cell class and xib file for the cell and then on each cell I am adding another UIView with a xib. In case you are wondering why, it is so I can add different UIViews to the cell. Right now I am only adding one.
Edit I have followed the WWDC 2012 video on creating a linelayout of a UICollectionViewCell with one difference. Instead of the cell in the middle getting bigger all the other cells get smaller.
Everything below is new to my question.
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *array = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
for (UICollectionViewLayoutAttributes *attributes in array){
if (CGRectIntersectsRect(attributes.frame, rect)) {
CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;
CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;
if (ABS(distance) < ACTIVE_DISTANCE) {
//THIS WOULD MAKE THE MIDDLE BIGGER
//CGFloat zoom = 1 + ZOOM_FACTOR *(1- ABS(normalizedDistance));
//attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
//attributes.zIndex = round(zoom);
} else {
//THIS MAKES ALL THE OTHERS NOT IN THE RECT SMALLER
CGFloat zoom = 1 + ZOOM_FACTOR *(1- ABS(normalizedDistance));
attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
attributes.zIndex = round(zoom);
}
}
}
return array;
}
The problem can be seen in the attached image.
Pink = Collection View Size
Brown = Cell size
Green = Cells Content size and an attached xib to the content size.
The problem I THINK I have is with the layout. When the sell is dequeued it is made smaller by the above code. Then when it is reused the CELL gets bigger again but the content view does not.
I have tired to manually set the frame of the content view but that does nothing.
UPDATE 1: This also only happens when I add a xib to the Cells content view. If there is no subview to the content view then there is no problem
UPDate 2: It appears that the subview of the cell, my xib is not resizing. I have tried to manually change its frame size but the only place this helps is in the cells drawrect method which feels like a hack to me.
reused cell not able to redraw itself so give call to
-(void)setFrame:(CGRect)frame {
[super setFrame:frame];
[self setNeedsDisplay]; // force drawRect:
}
from cellForItemAtIndexPath of the UICollectionView.
also have a look at this link
and this question
My answer is very specific and I am not sure it will help anyone.
The problem was that I had a constraint on the bottom of the grey view. After I changed this constraint to a less than or equal too then for some reason it worked.
Now I know this does not explain why it was not happening to every cell but it fixed my problem.
As such Harsh's answer might also be worth looking at if you have landed here after doing a search.
Edit: there also appears to be some bugs in the 6.0 UiCollectionView controller which seem to be fixed in 6.1

Large cells in a UICollectionView getting removed while the cell is still displayed

I have a UICollectionView that contains some large UICollectionViewCells. These cells are so large that they completely fill the UICollectionView bounds and extend off screen.
The problem is that the large cells are removed from the UICollectionView and queued for reuse while they are still displayed, resulting in a blank view. If I continue scrolling on the blank UICollectionView area, eventually the final portion of the cell appears and the start of the next cell appears in exactly the right place.
I've effectively disabled cell reuse and the problem still occurs apparently because the UICollectionView thinks that the cell is no longer displayed since no corner is within the bounds of the collection view.
To demonstrate make a collection view that is a single column and have a cell that is 10000px tall, when scrolling over the very tall cell it will disappear after about 1000px of content is scrolled off the screen and will reappear to display the final 1000px of content for the cell.
You can download a simple prototype app that displays this problem at: http://jack.cox.s3.amazonaws.com/collectionviewprototype.zip
This issue happened for me along with this warning in the debug log:
the behavior of the UICollectionViewFlowLayout is not defined because:
the item height must be less that the height of the UICollectionView
minus the section insets top and bottom values.
It seems that the out of the box UICollectionViewFlowLayout does not support cells larger than the screen.
This issue is being tracked as radar #12889164
Try this fix if you are still looking for a quick solution:
When a cell is detected to have a bigger height than the collectionview holding it, the collection view simply needs to be larger than the cell. So set the collecitonView frame to be bigger and correct the content and indicator insets.
- (void)updateCollectionViewForLargeCellHeight:(CGFloat)largeCellHeight {
CGFloat currentCollectionViewHeight = CGRectGetHeight(self.collectionView.frame);
if (largeCellHeight > currentCollectionViewHeight) {
self.collectionViewBottomConstraint = -largeCellHeight;
//This is the bottom constraint of the collectionView to its superview.
//If you are not using constraints, simply set the frame for the collectionView
UIEdgeInsets edgeInset = UIEdgeInsetsMake(0, 0, largeCellHeight, 0);
self.collectionView.contentInset = edgeInset;
self.collectionView.scrollIndicatorInsets = edgeInset;
[self.collectionView needsUpdateConstraints];
}
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize size;
[self updateCollectionViewForLargeCellHeight:size.height];
return size;
}
I have used UICollectionView with cells of the size of the screen. For iPad the cell size was 768x1024. And haven't found any issues. Please make sure that you have set the Min Spacing For Cells and For Lines are 0 Also return correct CGSize and UIEdgeInsets as follows
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize retval;
retval.width=maxWidth; //768 in case of iPad
retval.height=maxHeight; //1024 in case of iPad
return retval;
}
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0 , 0, 0, 0);
}

UITableView scrolling although numberOfRows is 0

I am having a very difficult time understanding this. I have a UITableView which frameHeight is set at 200. Although I've set numberOfRows to 0, this UITableView still scrolls, any idea why? My understanding is that it will only scroll if the contentView height is bigger than the frameHeight right? But in the case of the numberOfRows of 0, the contentView should be 0?
First Solution use UITableViewStyleGrouped style
Because by default it is set to UITableViewStylePlain which shows empty cells too after displaying filled cells.
Second Indirect Way
if (table.contentSize.height < table.frame.size.height) {
table.scrollEnabled = NO;
}
else {
table.scrollEnabled = YES;
}
You can run this code after calling reloadData on the table, and it calculates the right sizes and appears to work.
Edit 1
Another way is to disable Bounce -> Bounces/ Bounce Vertically
Hope this will solve your problem

How to limit the number of cells UITableview displays?

Im using a tableview to display some information in a quiz app that Im working on. My question is how do i make the tableview only show the number of cells that I need. Ive set the number of rows delegate method like this:
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
but at the bottom of the table view are empty cells that are not needed. If I set the tableview style to grouped I get 5 cells and no empty ones below them. Ive seen that other people have done this but cant seem to work it out. I was wondering if they have somehow added a custom view to the table footer to cancel the empty cells out?
Any ideas or help appreciated.
If you do want to keep the separator, you could insert a dummy footer view. This will limit the tableview to only show the amount of cells you returned in tableView:numberOfRowsInSection:
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
In swift:
self.tableView.tableFooterView = UIView(frame: CGRectZero)
A much nicer method which doesn't require cell resizing is to turn off the default separator (set the style to none) and then have a separator line in the cell itself.
I was having a similar problem, how to show only separators for the cells that contain data.
What I did was the following:
Disable separators for the whole tableView. You can do that in the
inspector for the tableview in Interface builder or by calling
[yourTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];.
Inside your cellForRowAtIndexPath where you populate your tableview with cells create a new UIView and set it as a subview to the cell. Have the background of this view lightgray and slightly transparent. You can do that with the following:
UIView *separatorView = [[UIView alloc] initWithFrame:CGRectMake:
(0, cell.frame.size.height-1,
cell.frame.size.width, 1)];
[separatorView setBackgroundColor:[UIColor lightGrayColor]];
[separatorView setAlpha:0.8f];
[cell addSubView:separatorView];
The width of this view is 1 pixel which is the same as the default separator, it runs the length of the cell, at the bottom.
Since cellForRowAtIndexPath is only called as often as you have specified in numberOfRowsInSection these subviews will only be created for the cells that possess data and should have a separator.
Hope this helps.
This worked for me - I had extra empty rows at the bottom of the screen on an iphone 5 -
In my case I needed 9 rows
- (CGFloat)tableView:(UITableView *)tabelView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return self.tableView.frame.size.height / 9;
}
You can implement heightForRowAtIndexPath: and compute the correct height to only show 5 cells on the screen.
Are you always going to have 5 rows? If it's a dynamic situation you should set the number of rows according to the datasource of the tableview. For example:
return [postListData count];
This returns the count of the records in the array holding the content.
The tableview is only going to display the number of rows and sections that you tell it to. If you're always going to have just a single section, DON'T implement the method below.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
Without this the tableview will only have 1 section. With it, as you would imagine, you can specify the number of sections.
It is quite Simple. Just set the size of the popover like this:
self.optionPickerPopOver.popoverContentSize = CGSizeMake(200, 200);
Certainly you can adjust the size (200,200) depending upon the size of contents and number if rows.
Easy way would be to shrink tableView size. I.e. 5 cells 20 points each gives 100.0f, setting height to 100.0f will cause only 5 rows will be visible. Another way would be to return more rows, but rows 6,7 and so would be some views with alpha 0, but that seems cumbersome. Have you tried to return some clerColor view as footerView?
I think u can try changing the frame of the table view, if you want to adjust with the number of cells.
Try something like this:
[table setFrame:CGRectMake(x, y, width, height*[list count])];
height refers to height of the cell
As Nyx0uf said, limiting the size of the cell can accomplish this. For example:
- (CGFloat)tableView:(UITableView *)tabelView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat result;
result = 100;
return result;
}
implement these two methods in your UITableViewController:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
if (section == tableView.numberOfSections - 1) {
return [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if (section == tableView.numberOfSections - 1) {
return 1;
}
return 0;
}
In fact, these codes are telling tableview that you don't need to render the seperator line for me anymore, so that it looks the empty cells won't be displayed(in fact , the empty cell can not be selected too)

Get a UITableView to scroll up from the bottom / snap to the bottom, not the top

I have a table view which is many cases will only have one or two cells that don't fill the screen. In this case, I would like the cells to sit at the bottom, rather than the top. In other words they should "snap" to the bottom of the tableview.
I can force the table view to scroll them to the bottom like this:
CGPoint bottomOffset = CGPointMake(0, [self.tableView contentSize].height - self.tableView.frame.size.height);
[self.tableView setContentOffset:bottomOffset animated:NO];
However, this is only partially successful. First, it doesn't work if I put it in viewDidLoad or viewWillAppear, only in viewDidAppear, which means that the user sees the tableview with the cells at the top first, then they move to the bottom. Second, if they scroll the table view, when they let go it automatically "snaps" back up to the top.
Does anyone know how to change this behaviour?
One option to consider is to resize the UITableView itself based on how many rows you will be displaying. Presuming that your UITableViewDelegate implements heightForRowAtIndexPath one can then set the height of the UITableView in a viewWillAppear method by multiplying the number of rows by the height of each row.
Something like this:
CGRect frame = [myTableView frame];
frame.size.height = [[myTableView dataSource] tableView: myTableView numberOfRowsInSection: 0] *
[[myTableView delegate] tableView: myTableView heightForRowAtIndexPath: [NSIndexPath indexPathForRow: 0 inSection: 0]];
[myTableView setFrame: frame];
This example assumes your table has one section and each row is the same height. Computing the size would have to get a little more complicated if multiple sections are involved or if different rows might be different heights.
Regardless of how the height is calculated the essence of the idea though is to just make the table itself shorter, no taller than the one or two rows that it is displaying, rather than trying to force it into behaving differently.