Remove spacing between UITableViewCells - iphone

I have UITableViewCells in the same section which have gaps between them. I coloured each cell's contentView background and did an NSLog to show that it's the same height as the cells.
Still, there's a gap between them. They're definitely in the same section as each other. Any ideas as to what could be causing the gap?

I'm not sure if you have used this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
And Checked that the Cell really is 78(just for arguments sake) in IB.
And then use:
tableView.sectionHeaderHeight = 0.0;
And set the style of the tableView:
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
And the last solution I've bumped into over the years is that sometimes you need to extend your background image with a pixel for some reason. I don't think this is a good solution at all, cause it doesn't really address the real problem, but rather puts a crappy bandaid on it.
cellFrameBackground.size.height += 1;

have you tried setting seperator style to none?
tableview.separatorType = UITableViewCellSeparatorStyleNone

If you are talking about a 1 pixel gap, that is the cell separator. You can remove this by setting a property on the table view:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
If you wanted to change the color of that separator use the separatorColor property.
If you are talking about a gap bigger than 1 pixel, can you post a screenshot and your cell code?

To add to the set of great answers, sometimes you just need to extend the background height as mentioned by Leeloo:
cellFrameBackground.size.height += 1;
Then, make your cell clip to bounds:
cell.clipsToBounds = YES;
And, voila.

Related

UICollectionView with paging some content is off screen Objective-c

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.

How to stop cells from indenting - shouldIndentWhileEditingRowAtIndexPath has no effect

I have a plain (not grouped) tableView with custom cells, and when I hit the Edit button, the cells indent. I don't want that, I want the deletion sign to lay right on top of my cell.
I tried shouldIndentWhileEditingRowAtIndexPath and also cell.shouldIndentWhileEditin = NO; as well as cell.indentionLevel = -3, but both won't have any effect. Any idea why?
Could this be due to my setup? I followed this tutorial, and I also tried a setup like Davyd suggested here, but the last did not only still indent my cells, it made it even worse, as the cells were indented, when I press Done.. and I can't get the background image to cover the whole cell...
So, anyone knows how to stop custom cells in a plain tableview from intending, while still showing the delete and move sign?
//EDIT:
btw, I build the custom cell in IB. I can take away the checkmark saying "Indent while Editing", it doesn't care. I can change the values for indention level and width, no effect. If i change the editing accessory, it happily displays it.
Hope that helps..
Thanks!
After a lot of research and trying pixel by pixel, it turned out, I needed to use -(void)layoutSubviews to "transit" from the original state to the original size.. If someone else ever needs to do that, here's my code, placed in my CustomCell.m:
- (void)willTransitionToState:(UITableViewCellStateMask)aState
{
[super willTransitionToState:aState];
self.state = aState;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// no indent in edit mode
self.contentView.frame = CGRectMake(0,
self.contentView.frame.origin.y,
self.contentView.frame.size.width,
self.contentView.frame.size.height);
if (self.editing )
{
NSLog(#"subview");
float indentPoints = self.indentationLevel * self.indentationWidth;
switch (state) {
case 3:
self.contentView.frame = CGRectMake(indentPoints,
self.contentView.frame.origin.y,
self.contentView.frame.size.width +124,// - indentPoints,
self.contentView.frame.size.height);
break;
case 2:
// swipe action
self.contentView.frame = CGRectMake(indentPoints,
self.contentView.frame.origin.y,
self.contentView.frame.size.width +75,// - indentPoints,
self.contentView.frame.size.height);
break;
default:
// state == 1, hit edit button
self.contentView.frame = CGRectMake(indentPoints,
self.contentView.frame.origin.y,
self.contentView.frame.size.width +80,// - indentPoints,
self.contentView.frame.size.height);
break;
}
}
}
Hope that helps :)
None of the above works for me, but this did:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}
This way your saying to the UITableView that you dont want any native styling when in edit mode, and instead you can take care of it yourself.
Have you checked that the delegate method tableView:shouldIndentWhileEditingRowAtIndexPath: is being called when you edit the cell?
The only time I used the tableView:shouldIndentWhileEditingRowAtIndexPath: delegate method
it worked fine.
// Override to prevent indentation of cells in editing mode (in theory)
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
Try changing the autoresizing mask of your content view or the elements inside your cell. The indent is because when your cell enters editing mode the content view is resized to show the accessories and the content moves with it.
It's hard to give specific advice without knowing what's in your cell, but you want to look at the fixed left or right margins.
I had the same problem. The reason is: They're not indented but auto-resized. The remove button is shown an the cell's view (and its subviews) are resized.
Solution is: Set the autosizing behavior of the custom table cell's subviews (the labels or whatever you placed on it) in InterfaceBuilder/Xcode as you need it.
I just realized that if you connect a UIView to the backgroundView outlet, it doesn't move at all. That combined with autoresizing flags is really all you need, I think.
Just tried this on iOS 6.
The shouldIndentWhileEditingRowAtIndexPath delegate method now works on plain table view as well.
----Edited-----
Well, as it turned out, it doesn't indent only if allowsMultipleSelection = YES

Adjusting row height correctly

Showing dynamic data in table cell make problem for me. I am using
[titleString sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(285,9999) lineBreakMode:UILineBreakModeWordWrap];
function for calculating the size now according to size i need to adjust row sizes. but it is inconsistent, Some time it give size(242,18) and (40,18) (showing width,height). when it gives more width for same height the it breaks in two line text and inconsistency begins. if i take less height then it overflow the text and if less in height then some time left a huge white space.
please help me and suggest some proper way for doing this.
you code seem me correct , there is only one place for modification left in your code that would be use CGFLOAT_MAX instead of 9999.
And Also check the lineBreakMode property, Assign numberOfLines With zero.
label.numberOfLines = 0;
label.lineBreakMode = UILineBreakModeWordWrap;
There is delegate method as follows
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == theRowWhereUwantToIncreaseTheSize)
{
return 105.0f;;
}
}

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)

Blurry UILabel as programmatic subview of UITableViewCell contentView

I am adding a UILabel instance as a subview of my custom UITableViewCell instance's contentView.
When I select the cell, the row is highlighted blue, except for the background of the label. The label text is sharp.
When I set the label and content view backgroundColor property to [UIColor clearColor], the label text becomes blurry.
How do I set the label background color to be clear, to allow the row highlight to come through, while still keeping the label text sharp?
One suggestion I read elsewhere was to round the label's frame values, but this did not have any effect.
CODE
Here is a snippet of my custom UITableViewCell subview's -setNeedsLayout method:
UILabel *_objectTitleLabel = [[UILabel alloc] initWithFrame:CGRectNull];
_objectTitleLabel.text = [self.awsObject cleanedKey];
_objectTitleLabel.font = [UIAppDelegate defaultObjectLabelFont];
_objectTitleLabel.highlightedTextColor = [UIColor clearColor]; //[UIAppDelegate defaultLabelShadowTint];
_objectTitleLabel.backgroundColor = [UIColor clearColor]; //[UIAppDelegate defaultWidgetBackgroundTint];
_objectTitleLabel.frame = CGRectMake(
kCellImageViewWidth + 2.0 * self.indentationWidth,
0.5 * (self.tableView.rowHeight - 1.5 * kCellLabelHeight) + kCellTitleYPositionNudge,
contentViewWidth,
kCellLabelHeight
);
_objectTitleLabel.frame = CGRectIntegral(_objectTitleLabel.frame);
_objectTitleLabel.tag = kObjectTableViewCellTitleSubviewType;
//NSLog(#"_objectTitleLabel: %#", NSStringFromCGRect(_objectTitleLabel.frame));
[self.contentView addSubview:_objectTitleLabel];
[_objectTitleLabel release], _objectTitleLabel = nil;
...
self.contentView.backgroundColor = [UIAppDelegate defaultWidgetBackgroundTint];
self.contentView.clearsContextBeforeDrawing = YES;
self.contentView.autoresizesSubviews = YES;
self.contentView.clipsToBounds = YES;
self.contentView.contentMode = UIViewContentModeRedraw;
The issue is sub-pixel rendering, which occurs when your origin (which is a float value) has a non-zero fractional component. Round to the nearest whole number and you should be fine.
In my case, having set shouldRasterize = YES on the CGLayer of the view containing the UILabel was the culprit. Removing that line made the text nice and crisp.
Ok found the problem, Make sure your parent view's coordinates are rounded as well.
I ran into this problem myself today, and read somewhere that non-integer values for the origin and size of the UILabel's frame can cause this (I know they're floats, but you know what I mean). There has got to be a more elegant solution, but this quick hack appears to have solved the problem for me:
self.valueLabel.frame = CGRectMake((int) frame.origin.x, (int) frame.origin.y, (int) frame.size.width, (int) frame.size.height);
If you find a better solution, please let me know, I'd love to replace this hack with something a bit more tasteful.
Another cause of garbled/blurry text is cell reuse. If you are de-queuing a reusable cell then it may redraw with different dimensions somewhere else and again be re-used when it gets to your cell with the garbled text.
To ensure the cells are unique be sure to allocate a new cell for the indicies where the text is garbled, and mark that UITableViewCell instance with a different reuse identifier. This is only practical of course if you're dealing with a very small number of cells and if you know exactly which cells are causing problems.
Setting shouldRasterize to YES may introduce blurriness. Set the rasterization scale and that should eliminate the blurriness. [self.layer setRasterizationScale:[[UIScreen mainScreen] scale]];
Sometimes the reason for the blurriness you have mentioned can be that labels's frame is beyond the cell frame.
Even if you see all of your text you have put inside the label on your cell, the actual label size can be bigger than the cell frame.
To check if that is the reason for the effect you see I would suggest to check/print all the data you have about labels size/location after it is instantiated and than check in the delegate method tableView:heightForRowAtIndexPath: that this fit into the cell height you are returning for the cell.
Hope it will help in your case.
Use round(); C functions are provided for a reason.
#define roundCGRectValues (frame) \
frame = CGRectMake(round(frame.origin.x),round(frame.origin.y),round(frame.size.width),round(frame.size.height));
All you need.
Does -setNeedsLayout get called even for dequeued reusable cells? If so, the cell will already have the label added to the content view, and you will draw it twice, making it blurry. You can inefficiently solve this by removing all of the content view's subviews before you add your subview:
for (UIView *subview in [[self contentView] subviews]) {
[subview removeFromSuperview];
}
A better solution would be to provide properties on your cell subclass to let you modify the content of a reused cell as-needed, rather than rebuilding its view hierarchy from scratch.