cell.selectedBackgroundView covering up UIViews in a cell - uiview

I have a table. Within each cell of a table, I created a simple bar graph (which is just 2 UIViews with background filled).
I have set cell.selectedBackgroundView to an image.
When the cell is selected, it seems to cover up parts of the bar graph. Does anyone know why?
The red is the selected cell. The top and bottom are unselected cells:
In the image, the grey bar, the brown bar, the 2 numbers (x.xx) and the semi-transparent line at the left, are all subviews of 1 UIView. The UIView is added to the cell. The line and the 2 numbers are still there, but the 2 bars are gone.
Here's some code:
Cell selected image set like this:
UIImage *selectedRowImage = [UIImage imageNamed:#"table-selectedcellbg-red-45px-stretch.png"];
cell.selectedBackgroundView = [[UIImageView alloc]initWithImage:[selectedRowImage resizableImageWithCapInsets:UIEdgeInsetsMake(selectedRowImage.size.height, selectedRowImage.size.width/2, selectedRowImage.size.height, selectedRowImage.size.width/2)]];
[cell sendSubviewToBack:cell.selectedBackgroundView]; // This didn't make a difference
Adding the view set like this:
UIView *graph = [barGraph getGraph];
UIView *graphView = [[UIView alloc]initWithFrame:CGRectMake(150, (tableView.rowHeight - graph.frame.size.height)/2, graph.frame.size.width, graph.frame.size.height)];
[graphView addSubview:graph];
[cell addSubview:graphView];
Any ideas?

I think the answer can be found in the UITableViewClass Reference:
selectedBackgroundView
...
Discussion
The default is nil for cells in plain-style tables
(UITableViewStylePlain) and non-nil for section-group tables
(UITableViewStyleGrouped). UITableViewCell adds the value of this
property as a subview only when the cell is selected. It adds the
selected background view as a subview directly above the background
view (backgroundView) if it is not nil, or behind all other views.
Calling setSelected:animated: causes the selected background view to
animate in and out with an alpha fade.
It seems as if selectedBackgroundView only works well if the corresponding backgroundView property of the cell is not nil.
Try adding a backgroundView and test again.
Hope that helps you out.
Edit:
Since this wasn't the solution, I tried to reproduce your problem, but with no success: the backgroundView stayed behind the QuestionMarkIcon (a view like your graphView)..
Code:
- (UITableViewCell*) tableView: (UITableView*) tableView cellForRowAtIndexPath: (NSIndexPath*) indexPath {
//...
UIImage* selectedRowImage = [UIImage imageNamed: #"strecheableImage.png"];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage: [selectedRowImage resizableImageWithCapInsets: UIEdgeInsetsMake(selectedRowImage.size.height, selectedRowImage.size.width/2, selectedRowImage.size.height, selectedRowImage.size.width/2)]];
UIView* graph = [[QuestionMarkIcon alloc] init];
UIView* graphView = [[UIView alloc]initWithFrame: CGRectMake(150, (tableView.rowHeight - graph.frame.size.height)/2, graph.frame.size.width, graph.frame.size.height)];
[graphView addSubview: graph];
[cell addSubview: graphView];
// ...
}
This is how my stretchableImage.png looks like:
Cell 1 is selected but the QuestionMarkIcon (your graph) stays in front:
Sorry I couldn't help.

Related

How to make UITableView looks like this

is it possible to make a distance between cells like that in standard UITableView? There is no options to make separator bigger. Also this distance from right and left.
you can do this by set your cell background to whatever background you want (let's say gray in this case) and in the cell, add a white uiview with left, right, and bottom margin like this:
Then go to your table view, set the separator as none
and one last step, set the background of your table view to the same gray background as your cell.
Then you don't have to do anything particularly in your code besides simply initial your table cell based on the custom nib file (i assume you want to do this anyway).
If you prefer to construct your cell in codes, you can use the same logic.
in method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
cell.backgroundColor = [UIColor whiteColor];
// This will create a line of 3 pixels that will be separating the cells
UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,3)];
separator.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separator];
// and if you want the border do left and right add:
UIView *separatorRx = [[UIView alloc] initWithFrame:CGRectMake(318,0,2,cell.frame.size.height)];
separatorRx.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separatorRx];
UIView *separatorSx = [[UIView alloc] initWithFrame:CGRectMake(0,0,2,cell.frame.size.height)];
separatorSx.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separatorSx];
return cell;
}
One way would be to set the backgroundView of the UITableViewCell to an UIImageView containing this white box on that gray background
You have to make a subclass of UITableViewCell. In your own subclass you may make everything you dream about! So, you need to add UIView with whiteColor background and margins as subview on your custom UITableViewCell.
There is not padding option in UITableView. You can either add a UIView in your UITableViewCell which will contains all the cell subviews, and change it's frame to create a padding right in the cell.
I suggest you to use UICollectionView instead, you can easily set the space between cells using a layout. If the cell is smaller than the actual collection View, then it's automatically centered.

Drawing line in UITableViewCell (without using drawRect)

I have a UITableViewCell in which I would like to draw some lines (say a 2pt line at 1/3rd from top of the TableCell covering the whole width). The lines would always be in the same place within the tableview cell.
One straightforward solution is to just have a -drawRect method that will use CGContextStrokePath to draw the line. But that seems to be like an overkill since it would call drawRect everytime which is inefficient.
I would think that there would be a way to be able to cache it somehow, so that all tableview cells are created with the lines by default. One way I can think of is to create 2pt*2pt png file and add it to a UIImageView on top of the tableview cell. Any other ways?
Try this -
Add this code in your cellForRowAtIndexPath, just adjust y position og this image view-
UIImageView *seperatedImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 49, 320, 1)];
seperatedImageView.backgroundColor = [UIColor colorWithRed:201.0/255.0 green:250.0/255.0 blue:152.0/255.0 alpha:1.0];
[cellBackView addSubview:seperatedImageView];
Another option is, to add a UIView and set its background color. For example:
UIView *lineView = [[[UIView alloc] initWithFrame:CGRectMake(0,0,cell.contentView.bounds.size.width, 2)] autorelease];
lineView.backgroundColor = [UIColor grayColor];
[cell.contentView addSubview:lineView];
You can just add a UIView like a subView of your UITableViewCell.

How to set clear background for UITableView Header with opaque body

How do I make the background for a tableHeaderView clear, but keep the rest of the UITableView background opaque?
I'm using a transparent tableHeaderView for a paralax effect. The object behind the tableView is a longer than the clear tableHeaderView "window" so I can center the visible data. This works well for longer lists as I can use the tableView as a mask, but when I don't have enough cells in the table the background object displays below the cells.
Relevant code:
self.tableView.backgroundView = nil;
self.tableView.backgroundColor = [UIColor whiteColor];
UIView *tableHeaderView = [[UIView alloc] initWithFrame: CGRectMake(0.0, 0.0, 320.0, 250.0)];
tableHeaderView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = tableHeaderView;
I've tried setting a background color for the tableView, but that makes the whole UITableView opaque (including the tableHeaderView), removing the "window" I have at the top.
Any ideas on how I can keep my transparent tableHeaderView while setting the body of the UITableView opaque?
Thanks!
After a couple days I was able to figure it out. The premise of the solution is to add a subview to the backgroundView of your table and change the subview's frame as you scroll.
The relevant code in viewDidLoad:
...
// Create the UIView that will become the tableView backgroundView
UIView *tableViewBackground = [[UIView alloc] initWithFrame:self.tableView.frame];
tableViewBackground.backgroundColor = [UIColor clearColor];
// Create the opaque backgroundView and set the frame so that it starts below the headerView
partialBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 250, 320.0, self.view.frame.size.height)];
partialBackgroundView.backgroundColor = [UIColor redColor];
// Add the partial background to the main background view and apply it to the tableView
[tableViewBackground addSubview:solidTableBodyBackgroundView];
self.tableView.backgroundView = tableViewBackground;
...
And then as you scroll, you can update the "visible window" in scrollViewDidScroll:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat scrollOffset = scrollView.contentOffset.y;
partialBackgroundView.frame = CGRectMake(0, 250 - scrollOffset, 320, self.view.frame.size.height);
// Other parallax code for scrolling
}
There may be better ways of doing this, but I found this to be pretty simple and it worked well.
A simpler way of doing the accepted answer for multiple sections
// Set the view for each cell with a clear color
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, SectionHeaderHeight)]; //
view.backgroundColor = [UIColor clearColor];
return view;
}
// Set the height of your desired header
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 10;
}
Here's a super late but quick and simple answer to this if like me you're returning a subclass of UITableViewHeaderFooterView as header view in your viewForHeaderInSection delegate method.
Setting myHeaderView.backgroundColor = UIColor.clear not helping you?
Try setting myHeaderView.layer.backgroundColor = UIColor.clear.cgColor instead.
Unless I'm misunderstanding something, you should be able to do this in two steps:
You will need to make the cells in your table opaque. Leave the tableView's background color set to [UIColor clearColor], and same goes for the views for your table header (and section headers if that applies).
Then take your table footer view (tableFooterView property of the UITableView), make it opaque, and make it very tall. When you only have a few cells in the table, the table footer will take up the rest of the screen.
Again, I might be misunderstanding something, but give that a go and see what you get. Good luck!
Swift-5, Transparent Section Header
Add a view and set its background as transparent
then return this view in ViewForSectionHeader method in tableView
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return viewForSection
}

Make UITableview cell transparent when it get selected

How to remove selection style color of UITableview while i select a particular cell ? When i change the selection style of cell to UITableViewCellSelectionStyleNone, the highlighted image doesn't appear in the cell. When i change that to UITableViewCellSelectionStyleBlue or UITableViewCellSelectionStyleGrey, the highlighted cell will distort will that particular gray or blue. My requirement is to make the cell with transparent background and when it gets selected, the selected image must show without selection style color.
I found the answer. Just put the below code inside cellForRowAtIndexpath method of willDisplayCell method
UIView *backView = [[UIView alloc] initWithFrame:CGRectZero];
backView.backgroundColor = [UIColor clearColor];
cell.backgroundView = backView;
cell.selectedBackgroundView = backView;
For customizing the selected cell background and its controls state, you needs to override the following method..
- (void)setSelected:(BOOL)selected animated:(BOOL)animated

How to set the "upper" border color on grouped UITableViewCells?

I've used -[UITableView setSeparatorColor:] to set the red border in the attached image. But how do I set the color of the border showing up as white?
EDIT: I know I can use the UITableViewSeparatorStyleSingleLine style to get rid of the white color entirely. But I don't want to do that: I want to change its color. Thanks!
The white color is because the separator style is set to Single Line Edged. If you change it to Single Line the white lines will disappear. Not sure if that solves your problem but I don't think you change the color without doing a lot more work.
Try making a "line view" for the cells. So in cellForRowAtIndexPath: method just add that to the cell that you need:
UIView *lineView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.contentView.bounds.size.width, 1)] autorelease];
lineView.backgroundColor = [UIColor whiteColor];
lineView.autoresizingMask = 0x3f;
[cell.contentView addSubview:lineView];
that will add that white line to the top of the each cell. If you don't want it for the very first row add an if-statement:
if (indexPath.row != 0)
{
UIView *lineView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.contentView.bounds.size.width, 1)] autorelease];
lineView.backgroundColor = [UIColor whiteColor];
lineView.autoresizingMask = 0x3f;
[cell.contentView addSubview:lineView];
}
Hope it helps.
You are trying to change the default iOS user interface but the change is so complex that it can't be done with the default properties.
What is the solution? Just remove the lines drawn by UITableVie (setting the color to [UIColor clearColor]) and customize UITableViewCell background.
Of course, you need 3 types of backgrounds - for the first cell, for the last cell and for the middle ones:
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath (NSIndexPath*)indexPath {
UITableViewCell* cell = [...];
UIView* background;
if (indexPath.row == 0) {
background = [...]; //background for the first cell
}
else if (indexPath.row + 1 == [self tableView:tableView numberOfRowsInSection:indexPath.section]) {
background = [...]; //background for the last cell
}
else {
background = [...]; //background for the middle cells
}
cell.backgroundView = background;
}
The question is how to create the background. Usually I just use an UIImageView or a combination of several UIImageView (rounded corner as one image and the lines as resizible images).
You can't.
This built-in drawing is specific to grouped-style tableView, and can't be changed (to my knowledge...)
There's a workaround to this (we've used -> sorry no source code), but i guess you're not going to like it :
1/ have information of each cell's position
2/ to re-implement drawing of EACH cell's background, depending on its position (so you have to save this position : FirstCell, MiddleCell, LastCell,) to reproduce the grouped tableView look.
A way to do this is with CoreGraphics :
From your subclassed CellGroupedBackgroundView (or customGroupedTableViewCell, depending on the design you choose) you create 2 nearly identical CAShapeLayers. Each one for each separator color. And you expose these colors as properties of your CellGroupedBackgroundView.
You set these layer's path depending on the position property you have set (using only CGPathAddLineToPointfor middle cells, and CGPathAddArcToPoint for first and last cell)
2/ use that created custom backgroundView on a plain UITableView, setting each cell's 'position' according to its indexPath...
Good luck :)

Resources