ios - view position inside cell tableview changes only after scrolling - ios

I have a tablewiew using ios 8.0+, i added a checkbox to each cell - on iphone 5 works great, but when testing on iphone 6 - the checkbox is in the right position only after scrolling...
(the second picture is after scrolling)
****cant add photos yet:) so what i actually see at first load is that the checkbox get some rightpadding -> after I scroll some of the checkboxes moves to the right - where they should be
Code below
Thank you!
CGFloat y =self.navigationController.navigationBar.frame.size.height + self.navigationController.navigationBar.frame.origin.y;
tableData = [[UITableView alloc] initWithFrame:CGRectMake(5, y+10, self.view.frame.size.width, self.view.frame.size.height - y -30 - nextButton.frame.size.height -10) style:UITableViewStylePlain];
tableData.dataSource = self;
tableData.delegate = self;
[self.view addSubview:tableData];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
else
{
CTCheckbox *check = [cell.subviews objectAtIndex:1];
[check removeFromSuperview];
}
CTCheckbox *checkbox;
cell.contentView.backgroundColor = [UIColor grayColor];
checkbox = [[CTCheckbox alloc] initWithFrame:CGRectMake(cell.frame.size.width-60, cell.frame.size.height/2-10, 50, 20.0)];
checkbox.alpha = 0.7;
[checkbox addTarget:self action:#selector(checkboxDidChange:) forControlEvents:UIControlEventValueChanged];
checkbox.tag = indexPath.row;
[checkbox setColor:[BlendedColors pink] forControlState:UIControlStateNormal];
//Expertise label
UIFont *myFont = [UIFont systemFontOfSize:12.0 ];
cell.textLabel.font = myFont;
cell.textLabel.text = [experties objectAtIndex:indexPath.row];
cell.textLabel.textColor = [BlendedColors black];
[cell addSubview:checkbox];
cell.selectionStyle = UITableViewCellStyleDefault;
if([[selectedCheckBox objectAtIndex:indexPath.row]isEqualToString:#"YES"])
{
checkbox.checked = YES;
}
else{
checkbox.checked = NO;
}
//cell.contentView.backgroundColor = [UIColor blackColor];
return cell;
}

Fixed - First cell width is always 320
added 3 lines
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//Fix Bug - first cell view is always 320 - now its dynamic(cell width = device width)
CGRect cellFrame = cell.frame;
cellFrame.size.width = self.view.frame.size.width;
cell.frame = cellFrame;
}

Related

ContentOffset issue in UIScrollView in UITableView

I've added a UIScrollView in each UITableViewCell of a UITableView.
This is my code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* CellIdentifier = #"Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIScrollView *propertyScrollView;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
propertyScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, tableView.frameWidth, 100)];
[propertyScrollView setContentSize:CGSizeMake(10*tableView.frameWidth, 100)];
[propertyScrollView setPagingEnabled:YES];
propertyScrollView.delegate = self;
propertyScrollView.tag = indexPath.row;
[[cell contentView] addSubview:propertyScrollView];
propertyScrollView.backgroundColor = [UIColor blackColor];
int pagingIndex = [[m_pagingIndexArray objectAtIndex:indexPath.row]intValue];
[propertyScrollView setContentOffset:CGPointMake(pagingIndex*propertyScrollView.frameWidth, 0)];
for(int i=0;i<10;i++)
{
UIButton *singleImage = [[UIButton alloc]initWithFrame:CGRectMake(i*tableView.frameWidth, 0, propertyScrollView.frameWidth, propertyScrollView.frameHeight)];
[propertyScrollView addSubview:singleImage];
singleImage.titleLabel.text = [NSString stringWithFormat:#"%d",i];
singleImage.titleLabel.textColor = [UIColor blackColor];
singleImage.titleLabel.font = systemFontBoldTypeOfSize(20);
[singleImage setImage:[horizentalImagesArray objectAtIndex:i] forState:UIControlStateNormal];
singleImage.backgroundColor = [UIColor whiteColor];
}
else
{
propertyScrollView.tag = indexPath.row;
int pagingIndex = [[m_pagingIndexArray objectAtIndex:indexPath.row]intValue];
[propertyScrollView setContentOffset:CGPointMake(pagingIndex*propertyScrollView.frameWidth, 0)];
}
return cell;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
int pageIndex = scrollView.contentOffset.x/scrollView.frameWidth;
[m_pagingIndexArray replaceObjectAtIndex:scrollView.tag withObject:[NSString stringWithFormat:#"%d",pageIndex]];
}
- (void)viewDidLoad {
[super viewDidLoad];
m_pagingIndexArray = [[NSMutableArray alloc]init];
for(int i=0;i<10;i++)
{
[m_pagingIndexArray addObject:#"0"];
}
}
I'm adding 10 UIButtons in a single UIScrollView(Paging Enabled).
The problem is, if I scroll any one of the UITableViewCell's scrollview and move to bottom cells, I can see some other UITableViewCell's scrollviews also scrolled to that content offset point.
I want all my UITableview cell's UIScrollView to scroll independently. How can I achieve it? Please help me to sort out this issue.
You are keeping the current page number in m_pagingIndexArray, and the same array is used for all the cells, so suppose if it contains the page number as 3, then it will be applicable for all the cells.
Also you need to reset the text and image of each button for each cell if it's being reused as I have added below-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = nil;
UIScrollView *propertyScrollView;
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
propertyScrollView = [[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, tableView.frameWidth, 100)] autorelease];
[propertyScrollView setContentSize:CGSizeMake(10*tableView.frameWidth, 100)];
[propertyScrollView setPagingEnabled:YES];
propertyScrollView.delegate = self;
propertyScrollView.tag = indexPath.row;
[[cell contentView] addSubview:propertyScrollView];
propertyScrollView.backgroundColor = [UIColor blackColor];
int pagingIndex = [[m_pagingIndexArray objectAtIndex:indexPath.row]intValue];
[propertyScrollView setContentOffset:CGPointMake(pagingIndex*propertyScrollView.frameWidth, 0)];
for(int i=0;i<10;i++)
{
UIButton *singleImage = [[[UIButton alloc]initWithFrame:CGRectMake(i*tableView.frameWidth, 0, propertyScrollView.frameWidth, propertyScrollView.frameHeight)] autorelease];
[propertyScrollView addSubview:singleImage];
singleImage.titleLabel.text = [NSString stringWithFormat:#"%d",i];
singleImage.titleLabel.textColor = [UIColor blackColor];
singleImage.titleLabel.font = systemFontBoldTypeOfSize(20);
[singleImage setImage:[horizentalImagesArray objectAtIndex:i] forState:UIControlStateNormal];
singleImage.backgroundColor = [UIColor whiteColor];
}
return cell;
}
Your code is correct for the case if cell is not reused, but as the cells are reused you need to set the content offset for scroll view of each cell if they are reused.
You need to write an else case -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(cell == nil)
{
// your code
}
else
{
// reset the content offset of the scroll view as per your needs for the reused cells
}
return cell;
}

UITextViews not cleared when selected in a UITableView

I'm implementing a UITableView with text-views as the content view of my cells.
The data that the user enters is saved in a settings dictionary when the user hits the return key:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == _textFieldOne){
[settingsDictionary setObject: _textFieldOne.text forKey:#"EntryOneText"];
[settingsDictionary stringValueForKey:#"textFieldOneValue"];
[self postNotificationSettingsUpdate:settingsDictionary];
didTestPostNotificationSettings = YES;
}
These saved values should be displayed in the text-field when the user returns back to the screen, which I've done using the code below:
//Set the value in the text fields from the settings dictionary
NSString *textFieldOneText = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMin"];
_textFieldOne.text = textFieldOneValue;
So far, everything seems to work as expected: text input is saved, and shown in the text-field when the user returns to screen. However, if the row of the TableView that holds the text-field is select (not the text-field itself), the text-field displays the behavior shown below:
It appears as if the text-field is showing both the newly inputted entry, as well as the entry that was last saved.
EDIT I'ved added more of my cellForRowAtIndexPath method below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForSubscribedRedZoneAlertRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RedZoneAlertCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
UISwitch *cellSwitch = nil;
NSNumber *position = enabledRedZoneAlertRows[indexPath.row];
switch (position.integerValue) {
case CarPerManHourRow: {
cell.textLabel.text = NSLocalizedString(#"Label", #"Label Row");
cellSwitch = [[UISwitch alloc] init];
cellSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:SwitchKey];
cellSwitch.tag = SwitchTag;
[cellSwitch addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = cellSwitch;
if ([[self.settingsDictionary valueForKey:#"RedZoneCarsPerManHrOnOff"]isEqual: #"1"]){
[cellSwitch setOn:YES];
}
break;
}
case TextFieldRow: {
static NSString *CellIdentifier = #"ConfigCell";
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
[cell.contentView addSubview:_textFieldOne];
[cell.contentView addSubview:_textFieldTwo];
[cell.contentView addSubview:_spacingLabel];
}
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
_textFieldOne = [[UITextField alloc]initWithFrame:CGRectMake(25, 0, 50, 30)];
_textFieldTwo = [[UITextField alloc]initWithFrame:CGRectMake(100, 0, 50, 30)];
_textFieldOne.delegate = self;
_textFieldTwo.delegate = self;
_textFieldOne.placeholder = #"Auto";
_textFieldTwo.placeholder = #"Auto";
[_textFieldOne setTextAlignment:NSTextAlignmentCenter];
[_textFieldTwo setTextAlignment:NSTextAlignmentCenter];
//Set the value in the text fields from the settings dictionary
NSString *textFieldOneText = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMin"];
NSString *textFieldTwoText = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMax"];
NSString *carsPerManHrMax = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMax"];
NSString *carsPerManHrMax = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMax"];
_textFieldOne.text = textFieldOneValue;
_textFieldTwo.text = textFieldTwoValue
_textFieldOne.backgroundColor = [UIColor whiteColor];
_textFieldTwo.backgroundColor = [UIColor whiteColor];
_textFieldOne.tintColor = [UIColor blackColor];
_textFieldTwo.tintColor = [UIColor blackColor];
[_textFieldOne.layer setCornerRadius:7.0f];
[_textFieldTwo.layer setCornerRadius:7.0f];
[_textFieldOne setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
[_textFieldTwo setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
_textFieldOne.returnKeyType = UIReturnKeyNext;
_textFieldTwo.returnKeyType = UIReturnKeyDone;
_spacingLabel = [[UILabel alloc] initWithFrame:CGRectMake(70, 0, 35, 30)];
_spacingLabel.text = #"–";
_spacingLabel.textColor = [UIColor colorWithRed:0.658 green:0.658 blue:0.658 alpha:1];
[_spacingLabel setTextAlignment:NSTextAlignmentCenter];
_spacingLabel.backgroundColor = [UIColor clearColor];
//[cell.contentView addSubview:_textFieldOne];
//[cell.contentView addSubview:_textFieldTwo];
//[cell.contentView addSubview:_spacingLabel];
break;
}
return cell;
}
EDIT TWO
Below is my attempt at fixing my issue based on jherran's answer. However, I am still experiencing the same problem.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForSubscribedRedZoneAlertRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RedZoneAlertCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
UISwitch *cellSwitch = nil;
NSNumber *position = enabledRedZoneAlertRows[indexPath.row];
switch (position.integerValue) {
case CarPerManHourRow: {
cell.textLabel.text = NSLocalizedString(#"Label", #"Label Row");
cellSwitch = [[UISwitch alloc] init];
cellSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:SWSettingCarsPerManHour];
cellSwitch.tag = SaveCarsPerManHourTag;
[cellSwitch addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = cellSwitch;
if ([[self.settingsDictionary valueForKey:#"RedZoneCarsPerManHrOnOff"]isEqual: #"1"]){
[cellSwitch setOn:YES];
}
break;
}
case CarsPerManHourConfigRow: {
static NSString *CellIdentifier = #"ConfigCell";
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
_carsPerManHourMinTextField = [[UITextField alloc]initWithFrame:CGRectMake(25, 0, 50, 30)];
_carsPerManHourMaxTextField = [[UITextField alloc]initWithFrame:CGRectMake(100, 0, 50, 30)];
_textFieldOne.delegate = self;
_textFieldTwo.delegate = self;
_textFieldOne.placeholder = #"Auto";
_textFieldTwo.placeholder = #"Auto";
[_textFieldOne setTextAlignment:NSTextAlignmentCenter];
[_textFieldTwo setTextAlignment:NSTextAlignmentCenter];
_textFieldOne.backgroundColor = [UIColor whiteColor];
_textFieldTwo.backgroundColor = [UIColor whiteColor];
_textFieldOne.tintColor = [UIColor blackColor];
_textFieldTwo.tintColor = [UIColor blackColor];
[_textFieldOne.layer setCornerRadius:7.0f];
[_textFieldTwo.layer setCornerRadius:7.0f];
[_textFieldOne setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
[_carsPerManHourMaxTextField setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
_textFieldOne.returnKeyType = UIReturnKeyNext;
_textFieldTwo.returnKeyType = UIReturnKeyDone;
_spacingLabel = [[UILabel alloc] initWithFrame:CGRectMake(70, 0, 35, 30)];
_spacingLabel.text = #"–";
_spacingLabel.textColor = [UIColor colorWithRed:0.658 green:0.658 blue:0.658 alpha:1];
[_spacingLabel setTextAlignment:NSTextAlignmentCenter];
_spacingLabel.backgroundColor = [UIColor clearColor];
NSLog(#"%#", _textFieldOne.text);
NSLog(#"%#",_carsPerManHourMaxTextField.text);
[cell.contentView addSubview: _textFieldOne];
[cell.contentView addSubview: _textFieldTwo];
[cell.contentView addSubview:_spacingLabel];
cell.tag = 1;
}
else {
_textFieldOne = (UITextField *)[cell.contentView viewWithTag:1];
_textFieldTwo = (UITextField *)[cell.contentView viewWithTag:1];
_spacingLabel = (UILabel *)[cell.contentView viewWithTag:1];
}
NSString * _textFieldOne = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMin"];
NSString *carsPerManHrMax = [self.settingsDictionary stringValueForKey:#"RedZoneCarsPerManHrMax"];
_textFieldOne.text = carsPerManHrMin;
_textFieldTwo.text = carsPerManHrMax;
How do I modify my code so that this behavior does not occur?
Check your cellForRowAtIndexPath, as cells are reused, you are probably not loading the cell property.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
/*
* This is an important bit, it asks the table view if it has any available cells
* already created which it is not using (if they are offscreen), so that it can
* reuse them (saving the time of alloc/init/load from xib a new cell ).
* The identifier is there to differentiate between different types of cells
* (you can display different types of cells in the same table view)
*/
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
/*
* If the cell is nil it means no cell was available for reuse and that we should
* create a new one.
*/
UILabel *label;
if (cell == nil) {
/*
* Actually create a new cell (with an identifier so that it can be dequeued).
*/
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier"] autorelease];
label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
cell.tag = 1;
[cell.contentView addSubview:label];
} else {
label = (UILabel *)[cell.contentView viewWithTag:1];
}
/*
* Now that we have a cell we can configure it to display the data corresponding to
* this row/section
*/
label.text = #"whatever";
}
EDIT: When your cell exits and it's reused, you are adding a view ([cell.contentView addSubview:_textFieldOne]) each time the cell is reused.
Ok, it is as I suspected. Every time the cell is taken out out the reuse queue, you create a new instance of textfield and add it to the content view. So basically the content view is piling up with new textfields.
What you should do is
1) to have a custom cell and make the cell the sole class responsible for its internals
2) expose only a configuration method to pass a raw text to cell
3) call that configuration method when thr cell is reused.
4) keep a reference to the textfield inside the custom cell to be able to update the text value any time incl. when it is recycled in cellforrowatindexpath

custom cell data not displayed ios

I need to display the cell data. Actually if I debug the code I can see that the cell.label.text does have correct value, but nothing is getting displayed on the simulator. I have set the row count in numberOfRowsInSection method.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"Cell";
LogTableCell *cell = (LogTableCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
CGRect frame1 = [ self.view frame];
frame1.origin.x=22.0f;
frame1.origin.y=55.0f;
frame1.size.width = 298.0f;
frame1.size.height= 425.0f;
[self.view.superview setFrame:frame1];
int btnWidth = ((self.view.frame.size.width-16)/3);
if(cell == nil)
{
cell = [[LogTableCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
LogItem *lg = [[LogItem alloc]init];
lg = [arrLogs objectAtIndex:indexPath.row ];
NSLog(#"%d",indexPath.row);
cell.lblname.textColor=[UIColor whiteColor];
cell.lblsubtype.textColor=[UIColor whiteColor];
cell.lbltime.textColor=[UIColor whiteColor];
cell.lblname.font=[UIFont fontWithName:#"Merriweather" size:15.0];
cell.lblsubtype.font=[UIFont fontWithName:#"Merriweather-Light" size:13.0];
cell.lbltime.font=[UIFont fontWithName:#"Merriweather-Light" size:13.0];
UIImageView *imageview = [[UIImageView alloc] initWithFrame:CGRectMake(1, cell.contentView.frame.size.height, 298.0,2)] ;
imageview.image = [UIImage imageNamed: #"lineseperator.png"];
[cell.contentView addSubview:imageview];
cell.lblname.text = lg.name;
NSLog(#"%#",lg.name);
[[cell imgtype] setImage:[UIImage imageNamed:lg.imagetype]];
if([lg.subtype length] == 0){
NSLog(#"%#",lg.subtype);
cell.lblsubtype.text = lg.time;
cell.lbltime.text = #"";
}
else{
NSLog(#"%#",lg.subtype);
cell.lblsubtype.text = lg.subtype;
cell.lbltime.text = lg.time;
}
return cell;
}
The imageview you're adding to the cell is covering all other content. You'll need to either resize/reposition it, or just use the already existing cell.imageView instead.

UITableView dequeue not working as expected

As I scroll down the list, all the rows are there, but they keep adding more subviews the more they appear on the visible frame
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuse = #"RuleCell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuse];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:reuse];
}
NSUInteger row = indexPath.row;
[self createCell: cell onRow: row];
return cell;
}
- (void) createCell: (UITableViewCell*)cell onRow: (NSUInteger)row
{
UIImageView* bgImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell_background_spade_active.png"]];
cell.backgroundView = bgImage;
cell.textLabel.hidden = YES;
UILabel* titleLabel = [[UILabel alloc] initWithFrame: CGRectMake(100, CGRectGetHeight(cell.frame) / 2, 200, 50)];
titleLabel.text = [[self.ruleList objectAtIndex: row] objectForKey: TitleKey];
titleLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: titleLabel];
}
I think you need to execute almost all of the logic that's in createCell: only within the if (cell == nil){ segment of your code. The part that should execute where you're currently calling createCell: is just getting a reference to the titleLabel and setting its text value.
To clarify, here's the kind of modification I'm suggesting (not tested, but should give the right idea):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuse = #"RuleCell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuse];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:reuse];
[self setUpCell: cell];
}
NSUInteger row = indexPath.row;
UILabel *titleLabel = (UILabel *)[cell.contentView viewWithTag:42];
titleLabel.text = [[self.ruleList objectAtIndex: row] objectForKey: TitleKey];
return cell;
}
- (void) setUpCell: (UITableViewCell*)cell
{
UIImageView* bgImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell_background_spade_active.png"]];
cell.backgroundView = bgImage;
cell.textLabel.hidden = YES;
UILabel* titleLabel = [[UILabel alloc] initWithFrame: CGRectMake(100, CGRectGetHeight(cell.frame) / 2, 200, 50)];
titleLabel.tag = 42;
titleLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: titleLabel];
}

iOS create a invisible space between cells

I have a standard tableview here and I wanted to be able to add a space between each cell that is invisible/hidden that shows the background. What is the correct way of doing it?
Here is the code I am using:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
JointCAD *currentCall = [[xmlParser calls] objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
// Format each frame that holds each piece of content in each row
CGRect countyImageFrame = CGRectMake(275, 6, 18, 18);
UIImageView *countyImageLabel = [[UIImageView alloc] initWithFrame:countyImageFrame];
countyImageLabel.tag = 0016;
countyImageLabel.backgroundColor = BG_COLOR
[cell.contentView addSubview:countyImageLabel];
CGRect callTypeImageFrame = CGRectMake(275, 30, 18, 18);
UIImageView *callTypeImageLabel = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
callTypeImageLabel.tag = 0017;
callTypeImageLabel.backgroundColor = BG_COLOR
[cell.contentView addSubview:callTypeImageLabel];
CGRect callTypeFrame = CGRectMake(5, 2, 175, 15);
UILabel *callTypeLabel = [[UILabel alloc] initWithFrame:callTypeFrame];
callTypeLabel.tag = 0011;
callTypeLabel.backgroundColor = BG_COLOR
callTypeLabel.numberOfLines = 2;
callTypeLabel.font = [UIFont boldSystemFontOfSize:12];
[cell.contentView addSubview:callTypeLabel];
CGRect locationFrame = CGRectMake(5, 21, 175, 10);
UILabel *locationLabel = [[UILabel alloc] initWithFrame:locationFrame];
locationLabel.tag = 0014;
locationLabel.backgroundColor = BG_COLOR
locationLabel.numberOfLines = 2;
locationLabel.font = [UIFont systemFontOfSize:10];
[cell.contentView addSubview:locationLabel];
CGRect unitsFrame = CGRectMake(3, 40, 175, 10);
UILabel *unitsLabel = [[UILabel alloc] initWithFrame:unitsFrame];
unitsLabel.tag = 0012;
unitsLabel.backgroundColor = BG_COLOR
unitsLabel.textColor = [UIColor blackColor];
unitsLabel.font = [UIFont italicSystemFontOfSize:10];
[cell.contentView addSubview:unitsLabel];
CGRect stationFrame = CGRectMake(185 , 28, 85, 20);
UILabel *stationLabel = [[UILabel alloc] initWithFrame:stationFrame];
stationLabel.tag = 0013;
stationLabel.backgroundColor = BG_COLOR
stationLabel.font = [UIFont boldSystemFontOfSize:12];
[cell.contentView addSubview:stationLabel];
CGRect callnumberFrame = CGRectMake(185 , 5, 80, 20);
UILabel *callnumberLabel = [[UILabel alloc] initWithFrame:callnumberFrame];
callnumberLabel.tag = 0015;
callnumberLabel.backgroundColor = BG_COLOR
callnumberLabel.font = [UIFont boldSystemFontOfSize:12];
[cell.contentView addSubview:callnumberLabel];
}
// Display content in each cell
if ([currentCall.county isEqualToString:#"W"]) {
UIImage *countyImage = [UIImage imageNamed:#"blue.png"];
UIImageView *countyImageLabel = (UIImageView *)[cell.contentView viewWithTag:0016];
countyImageLabel.image = countyImage;
}
else {
UIImage *countyImage = [UIImage imageNamed:#"green.png"];
UIImageView *countyImageLabel = (UIImageView *)[cell.contentView viewWithTag:0016];
countyImageLabel.image = countyImage;
}
if ([currentCall.callType isEqualToString:#"F"]) {
UIImage *callTypeImage = [UIImage imageNamed:#"red.png"];
UIImageView *callTypeImageLabel = (UIImageView *)[cell.contentView viewWithTag:0017];
callTypeImageLabel.image = callTypeImage;
}
else {
UIImage *callTypeImage = [UIImage imageNamed:#"yellow.png"];
UIImageView *callTypeImageLabel = (UIImageView *)[cell.contentView viewWithTag:0017];
callTypeImageLabel.image = callTypeImage;
}
UILabel *callTypeLabel = (UILabel *)[cell.contentView viewWithTag:0011];
callTypeLabel.text = [currentCall currentCallType];
UILabel *locationLabel = (UILabel *)[cell.contentView viewWithTag:0014];
locationLabel.text = [currentCall location];
UILabel *unitsLabel = (UILabel *)[cell.contentView viewWithTag:0012];
unitsLabel.text = [currentCall units];
NSString *station = [#"Station: " stringByAppendingString:currentCall.station];
UILabel *stationLabel = (UILabel *)[cell.contentView viewWithTag:0013];
stationLabel.text = station;
NSString *callnumber = [#"Call No: " stringByAppendingString:currentCall.callnumber];
UILabel *callnumberLabel = (UILabel *)[cell.contentView viewWithTag:0015];
callnumberLabel.text = callnumber;
cell.backgroundColor = BG_COLOR
return cell;
}
// Set how tall each cell is
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 55;
}
Let me start by saying I did not read all your code. That said I have done exactly this. The first approach is to declare in the heightForCell a larger value for the cell above where the gap should be. The cell.contentView might need to have its clipToBounds set. I believe in this case the cell size should be set by setting the cell.frame.size (the origin is 0,0), and the contentsView and backgroundview properly sized too.
The second way to do it is to insert empty cells - cells with a different reuse identifier, and which are just empty cells with everything set to have a clear color.
Just use the trick to have spaces between each cells..
static NSString *CELL_ID2 = #"SOME_STUPID_ID2";
// even rows will be invisible
if (indexPath.row % 2 == 1)
{
UITableViewCell * cell2 = [tableView dequeueReusableCellWithIdentifier:CELL_ID2];
if (cell2 == nil)
{
cell2 = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CELL_ID2];
[cell2.contentView setAlpha:0];
[cell2 setUserInteractionEnabled:NO]; // prevent selection and other stuff
}
return cell2;
}
I just use different heights and alternate colours between cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
if (indexPath.row % 2 == 1)
{
static NSString *CellIdentifier = #"cellID1";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor colorWhite];
return cell;
} else {
static NSString *CellIdentifier2 = #"cellID2";
UITableViewCell *cell2 = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell2 == nil) {
cell2 = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier2];
}
cell2.backgroundColor = [UIColor clearColor];
return cell2;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 2 == 1) {
return 40.0;
} else {
return 2.0;
}
}

Resources