UICollectionViewCell -- make selectedBackgroundView bigger than cell itself - ios

I am trying to figure out a way to make my selectedBackgroundView of a cell, larger than the cell itself.
My following approach aims to make the selectedBackgroundView:
the cell's superview width (the entire width of the screen) X the cell's height
UIView *bg = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.superview.frame), CGRectGetHeight(cell.frame))];
bg.backgroundColor = [UIColor redColor];
cell.selectedBackgroundView = bg;
When this cell is selected, the background color only extends within the cell's limits (not up to the superview's height)
How can I best accomplish making the selectedBackgroundView larger than the cell? Am I taking the complete wrong approach here?

as I tested, selectedBackgroundView's frame is constant, your bg's width change does not work.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell * cell = [tableView cellForRowAtIndexPath: indexPath];
CGRect f = CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height);
f.size.height += 20;
f.origin.y -= 10;
UIView *bg = [[UIView alloc] initWithFrame: f];
bg.backgroundColor = [UIColor redColor];
[cell.contentView addSubview: bg];
cell.contentView.clipsToBounds = false;
}

Related

unwanted white space "under" tableView subview when tableView scrolled to its content limits

I have a UITableViewCell as a subview in a custom view controller. It works great except that when it scrolls to its top or bottom of its contentSize limit, it "keeps going" and leaves some white space exposed behind it. This is particularly irritating because I do have a UIView covering the entire screen behind the tableView, and that view is set to a non-white color. I also added a subview exactly underlaying the tableview with the same background color, again attempting to block the white. I also set the UIApplication Window background color to a non white color. None of this worked.
I would have thought that even if my TableView bounces around its origin frame, the "exposed" view should match the underlying view rather than be white. How can I fix my tableView so that it retains all its scroll properties but doesn't reveal white when it bounces around at the end of a scroll?
Here is a screen shot of the effect. The white appears the tableViewHeader and below a UISCrollView that occupies the top of the screen. This appears when I scroll the tableView all the way to one extreme. The white space appears at the bottom rather than the top of the tableView if I scroll all the way to the other end.
Here's the relevant code, quite vanilla I think:
#interface JudgeViewController () <UITextFieldDelegate, UITextViewDelegate, UINavigationControllerDelegate, UIGestureRecognizerDelegate, UITableViewDataSource, UITableViewDelegate, UIViewControllerRestoration, UIScrollViewDelegate>
#property (nonatomic) UITableView *tableView;
#end
functions to set tableViewCells
#pragma mark - tableview appearance and actions
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
StatsViewController *svc = [[StatsViewController alloc] init];
svc.user = self.object.answerUser[indexPath.row];
svc.fromJudge = YES;
[self.navigationController pushViewController:svc animated:YES];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.object.answerArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
UILabel *label = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(cell ==nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero];
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode: UILineBreakModeWordWrap];
[label setMinimumFontSize:SMALL_FONT_SIZE];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:SMALL_FONT_SIZE]];
[label setTag:1];
// [[label layer] setBorderWidth:2.0f];
[[cell contentView] addSubview:label];
}
CGFloat width = [[UIScreen mainScreen] bounds].size.width;
CGFloat height = [[UIScreen mainScreen] bounds].size.height;
NSString *text = self.object.answerArray[indexPath.row];
CGSize constraint = CGSizeMake(.8*CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN)*2, 200000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:SMALL_FONT_SIZE] constrainedToSize:constraint];
if(!label)
label = (UILabel *)[cell viewWithTag:1];
[label setText:text];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, .8*CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN)*2, MAX(size.height, 44.0f))];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectMake(.85*width, label.frame.size.height/2-2*CELL_CONTENT_MARGIN, .12*width, 20);
[button1 setTitle:#"UP" forState:UIControlStateNormal];
button1.titleLabel.font =[UIFont systemFontOfSize:SMALLEST_FONT_SIZE];
[button1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button1 addTarget:self action:#selector(upVoteA:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button1];
[cell.contentView bringSubviewToFront:button1];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button2.frame = CGRectMake(.85*width, label.frame.size.height/2+2*CELL_CONTENT_MARGIN, .12*width, 20);
[button2 setTitle:#"DOWN" forState:UIControlStateNormal];
button2.titleLabel.font =[UIFont systemFontOfSize:SMALLEST_FONT_SIZE];
[button2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button2 addTarget:self action:#selector(downVoteA:) forControlEvents:UIControlEventTouchUpInside];
CGFloat moduloResult = indexPath.row % 2;
if(moduloResult>0)
{
cell.backgroundColor = [UIColor colorWithRed:1 green:0.647 blue:0 alpha:.6];
}
else
{
cell.backgroundColor = [UIColor colorWithRed:1 green:0.647 blue:0 alpha:.4];
}
cell.opaque = NO;
cell.alpha = 0.2;
[cell.contentView addSubview:button2];
[cell.contentView bringSubviewToFront:button2];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(void)keyboardToJudge
{
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row < [self.object.answerArray count])
{
NSString *text = self.object.answerArray[indexPath.row];
CGSize constraint = CGSizeMake(.8*CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN)*2, 200000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE-2.0f] constrainedToSize:constraint];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN)*2;
}
else
{
return 200.0f;
}
}
functions setting out layout:
-(void)viewDidLoad
{
...among other things setting up top scroll view (top part of view with gray background and orange text)...
if(self.navigationController.navigationBar.frame.size.height>0)
{
self.scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 5, width, height*SCROLL_VIEW_OFFSET)];
}
else
{
self.scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, statusBarHeight+5, width, height*SCROLL_VIEW_OFFSET)];
}
self.scroll.backgroundColor = BACKGROUND_COLOR;
self.scroll.contentSize =CGSizeMake(width, .5*height);
self.scroll.delegate = self;
self.scroll.contentInset = UIEdgeInsetsMake(30, 0, 30, 0);
[self.scroll setShowsHorizontalScrollIndicator:NO];
...adding buttons to self.scroll...
[self.view addSubview:self.scroll];
....
self.tableView = [[UITableView alloc] initWithFrame:frame];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _width, _height*.1)];
self.tableView.tableFooterView.backgroundColor = BACKGROUND_COLOR;
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _width, _height*.1)];
self.tableView.tableHeaderView.backgroundColor = BACKGROUND_COLOR;
....tableView hidden state is changed to yes in another function if row count is zero but not usually...
self.tableView.hidden = NO;
[self.view addSubview:self.tableView];
...
}
Finally, I also call :
[self.tableView reloadData];
after reloading data from a webserver and depending on the results either set the tableView to hidden or not (not hidden if there are results to display). That should be every line of code that touches the tableView subview.
Add to your viewDidLoad
[self.tableView setBackgroundColor:BACKGROUND_COLOR];
Set the background color of your tableView and you'll be fine
Change this line:
self.scroll.contentInset = UIEdgeInsetsMake(30, 0, 30, 0);
To this:
self.scroll.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
You are adding a footer to your tableview with that line. The following image is from the IOS dev Library
Set the table view estimate to 0 (Uncheck Automatic) in the size inspector

Making a TableViewCell Section Footer Transparent

I am trying to make a section footer of a UITableViewCell transparent and this is what I am doing right now:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIColor *background = [UIColor clearColor];
UIImageView *imageView = [[UIImageView alloc] initWithImage:(UIImage *)background];
imageView.frame = CGRectMake(10,10,1,30);
return imageView;
}
But I am getting a problem from casting background to a UIImage. Is this possible in this way, is there a better way to cast it or am I simply going about this wrong? I am basically using the footer as a way to create a clear spacer between cells. Need some guidance on this.
This code will add clear footer to your section, where you can set the desired height to whatever you need. Below it has been set to 30, to match your code in the question.
-(UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView *footerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 30)];
footerView.backgroundColor = [UIColor clearColor];
return footerView;
}
Instead of type casting the colour into the UIImage, use the backgroundColor property :
Try this :
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10,10,1,30)];
imageView.backgroundColor = [UIColor clearColor];

UITableView extend different background color below cells

I have a UITableView that I have given a headerView that has a green background. I have also given the UITableView that same green background color so that when the tableView is pulled down it feels like a seemless color above the tableView. Works perfectly.
The problem is my tableView only has 4 rows, and below that it shows the green color again.
How can I show white below the rows instead so that I only see the green background color when pulling down the tableView?
You can add an extra top view, same as in this answer to UIRefreshControl Background Color:
CGRect frame = self.tableView.bounds;
frame.origin.y = -frame.size.height;
UIView *bgView = [[UIView alloc] initWithFrame:frame];
bgView.backgroundColor = [UIColor greenColor];
[self.tableView insertSubview:bgView atIndex:0];
You could add a fifth cell with no content, and make it, say 400 points high, and limit the size of the table's contentView so that you can't scroll to the bottom of that cell.
-(void)viewWillLayoutSubviews {
self.tableView.contentSize = CGSizeMake(self.tableView.frame.size.width, 500);
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat h = (indexPath.row == 4)? 400:44;
return h;
}
Putting the contentSize setting in viewWillLayoutSubviews ensures that it will be reset to that value if you rotate your device.
as I said in these comments, in this way the headerView will be under the navigationBar and if you pull down the tableview you will see the headerView green. So you can set white color for tableView:
(i tested it and work)
-(void) viewDidLoad {
self.tableView.backgroundColor = [UIColor whiteColor];
headerView = [[UIView alloc] init];
headerView.backgroundColor = [UIColor greenColor];
UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(0, -50, 320, 120)];
lab.backgroundColor = [UIColor greenColor];
[headerView addSubview:lab];
self.tableView.tableHeaderView = headerView;
}
#pragma mark - Table view data source
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 80;
}
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return headerView;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
Same as the accepted answer - in Swift 5:
var frame : CGRect = self.tableView.bounds
frame.origin.y = -frame.size.height
let bgView : UIView = UIView.init(frame: frame)
bgView.backgroundColor = UIColor.green
self.tableView.insertSubview(bgView, at: 0)
Also add the following code (right after the above code) to make sure it works for other sized devices:
bgView.translatesAutoresizingMaskIntoConstraints = true
bgView.autoresizingMask = [UIView.AutoresizingMask.flexibleWidth]

UITableView center a UIImage and UILabel in viewForHeaderInSection

I wanna center vertically and horizontally an image inside of HeaderSection and a label inside of the image. But I don't have a clear idea about how make that. My code is:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIImage *image = [UIImage imageNamed:#"bg_title_category"];
UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)] autorelease];
UILabel *sectionTitle = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 30)] autorelease];
UIImageView *sectionHeaderBG;
sectionTitle.text = #"Trial"; //[[tableDataSource objectAtIndex: section] objectForKey: #"Title"];
sectionTitle.textAlignment = NSTextAlignmentCenter;
sectionTitle.font = [UIFont fontWithName:#"Helvetica-Bold" size:14];
sectionTitle.textColor = [UIColor whiteColor];
sectionTitle.shadowColor = [UIColor colorWithWhite:0 alpha:0.4];
sectionTitle.shadowOffset = CGSizeMake(1, 1);
sectionTitle.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
sectionHeaderBG = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _tableView.frame.size.width/2, image.size.height)];
sectionHeaderBG.image = [UIImage imageNamed:#"bg_title_category"];
[headerView addSubview:sectionHeaderBG];
[headerView addSubview:sectionTitle];
return headerView;
}
But this code not center anything... Thanks in advance!
The problem is that you're creating headerView with origin (0,0) and it's size the same one as your image; then you're adding all of your views to headerView. When the table view adds this header view it will not be centered, rather it'll placed at (0,0).
What I'd suggest you to do is to create headerView with the same origin (0,0) but with the width of your tableView and the height depening on you. Let's just assume for now the height will be the same as your image plus 10px at the top and bottom just to give it some margin. Then you can add your UIImageView and UILabel inside headerView and center them with respect to it. It'd be something like this:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIImage *image = [UIImage imageNamed:#"bg_title_category"];
// Create your headerView with the same width as the tableView and a little taller than the image
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0, tableView.bounds.size.width, image.size.height + 20)]; //10px top and 10px bottom. Just for illustration purposes.
// Create the image view
UIImageView *sectionHeaderBG = [[UIImageView alloc] initWithImage:image];
// Now center it and add it to headerView
sectionHeaderBG.center = CGPointMake(headerView.bounds.size.width/2, headerView.bounds.size.height/2);
[headerView addSubview: [sectionHeaderBG autorelease]];
// Now it's turn of the label. Again I suggest using the tableView's width
UILabel *sectionTitle = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 30)];
// Now center it. You could even do this when creating it's frame
sectionTitle.center = CGPointMake(headerView.bounds.size.width/2, headerView.bounds.size.height/2);
// do the rest of the configuration for your label...
// and add it to headerView
[headerView addSubview: [sectionTitle autorelease]];
return [headerView autorelease];
}
Hope this helps!

Adding uiTextView before uiScrollView

I want the textview to be before the scrollview inside my tablecell like this, so that the scrollview scrolls and the titles stays put.
[Title goes here] - it does not move with the scrollview
---------------------
| |
| ScrollView |
| |
---------------------
This is my code, the textView appears behind the scrollview.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
}
NSInteger numberOfViews = 10;
UIScrollView *vwScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 1280, 200)];
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i * 250;
UITextView *titleView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 1280, 20)];
titleView.text = #"Title";
[titleView setFont:[UIFont fontWithName:#"HelveticaBold" size:32]];
UIView *awesomeView = [[UIView alloc] initWithFrame:CGRectMake(xOrigin, 0, 250, 180)];
awesomeView.backgroundColor = [UIColor colorWithRed:0.5/i green:0.5/i/10 blue:0.5 alpha:1];
[awesomeView.layer setBorderColor:[UIColor whiteColor].CGColor];
[awesomeView.layer setBorderWidth:10.5f];
awesomeView.layer.shadowPath = [UIBezierPath bezierPathWithRect:awesomeView.bounds].CGPath;
[cell.contentView addSubview:titleView];
[vwScroll addSubview:awesomeView];
}
vwScroll.contentSize = CGSizeMake(250 * numberOfViews, 200);
[cell.contentView addSubview:vwScroll];
return cell;
}
Why cant you just set the frame of your titleView to, say, (0,0,width,titleHeight) and then set the frame of your scrollView to (0,titleHeight,width,cellHeight-titleHeight).
This will just place the title at the top part of the cell, setting it's height to whatever you make titleHeight to be, and will put the scrollView at the bottom part of the cell, setting it's height to the rest of the cell.

Resources