Can I give space between UITableViewCell - ios

I would like to give space of 10 pixel in each table view cell.
How I can do that?
Right now all cells are coming without any space
Here is my cell function
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"MyOrderCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
NSLog(#"%d",indexPath.row);
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
UILabel *orderid = (UILabel*)[cell.contentView viewWithTag:101];
orderid.textColor = kMaroonColor;
orderid.font = [UIFont fontWithName:kFontName size:kProductFont];
orderid.text = [NSString stringWithFormat:#"ORDER ID : %#",contentDict[#"order_id"]];
UILabel *date = (UILabel*)[cell.contentView viewWithTag:102];
date.textColor = kMaroonColor;
date.font = [UIFont fontWithName:kFontName size:kProductFont];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *date1 = [dateFormat dateFromString:contentDict[#"order_date"]];
// Convert date object to desired output format
[dateFormat setDateFormat:kDateFormat1];
NSString *dateStr = [dateFormat stringFromDate:date1];
date.text = dateStr;
NSArray *products = contentDict[#"products"];
UILabel *noOfProducts = (UILabel*)[cell.contentView viewWithTag:103];
noOfProducts.textColor = kMaroonColor;
noOfProducts.font = [UIFont fontWithName:kFontName size:kProductFont];
noOfProducts.text= [NSString stringWithFormat:#"NO OF PRODUCTS : %d",products.count];
NSArray *totalArray = contentDict[#"totals"];
NSDictionary *totalDict = [totalArray objectAtIndex:0];
UILabel *price = (UILabel*)[cell.contentView viewWithTag:104];
price.textColor = [UIColor blackColor];
price.font = [UIFont fontWithName:kFontName size:kProductFont];
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"\u20B9 %#",totalDict[#"total"]]];
[attributeString addAttribute:NSForegroundColorAttributeName
value:kGreyColor
range:NSMakeRange(0, 1)];
price.attributedText = attributeString;
UIView* shadowView = [[UIView alloc]init];
[cell setBackgroundView:shadowView];
// border radius
[shadowView.layer setCornerRadius:10.0f];
// border
[shadowView.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[shadowView.layer setBorderWidth:1.5f];
// drop shadow
[shadowView.layer setShadowColor:[UIColor blackColor].CGColor];
[shadowView.layer setShadowOpacity:0.8];
[shadowView.layer setShadowRadius:3.0];
//[cell.layer setShadowOffset:CGSizeMake(5.0, 5.0)];
[tableView setSeparatorInset:UIEdgeInsetsMake(10, 10, 10, 10)];
[cell setLayoutMargins:UIEdgeInsetsMake(10, 10, 10, 10)];
// [tableView setIndentationWidth:10];
// [tableView setIndentationLevel:2];
//tableView.separatorStyle=UITableViewCellSeparatorStyleSingleLine;
return cell;
}

The most simple way would be make your cells height a bit bigger(3pt from top and 7pt from the bottom) than that of your cell's background image, and making the colour as [UIColor clearColor]. That would give the illusion that the cells have a 10 pt gap in between.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// number of cells or array count
return 10;
}
- (NSInteger)tableView:(UITableView *)tableViewnumberOfRowsInSection:(NSInteger)section
{
return 1;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
// space between cells
return 10;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [UIView new];
[view setBackgroundColor:[UIColor clearColor]];
return view;
}

In the user interface for UITableView set Row Height Attribute value 210.
and In the user interface for UITableViewCell set Row Height Attribute value 200.
It will put 10 px space between each cell in the TableView

just make numberOfSections = "Your array count" and make each section contains only one row. And then define headerView and its height.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return yourArry.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return cellSpacingHeight;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *v = [UIView new];
[v setBackgroundColor:[UIColor clearColor]];
return v;
}

Create a container view inside UITableviewCell->ContentView. You keep all your subviews(labels,buttons,views) inside that container view. Now set container's boundaries away from the Cell's contentview by setting appropriate constraints.
UITableviewCell->ContentView->YourCustomContainerView-> (all
subviews). Set YourCustomContainerView's boundaries away from the
ContentView.

I guess the best way is to add a separator cell for each normal cell. let each kind of cell do its own job, and you can reuse the the separator and normal cell else where and need not to change their UI again. and you can customize the separator as you want, and all the calculations are easy, easy like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return dataArray.count * 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row % 2 == 0) {
CellForData *cell = [tableView dequeueReusableCellWithIdentifier:#"dataCellID" forIndexPath:indexPath];
return cell;
}else{
CellForSeparation *cell = [tableView dequeueReusableCellWithIdentifier:#"separatorCellID" forIndexPath:indexPath];
return cell;
}
}

If for a simple solution you can create sections for all cells. Each section each row. You can add a footer height for spacing between sections.

its so simple
you can set the auto layout or adjust the Hight of the label
as well increases the hight of the cell

Increase the cell Hight.... And hide the separator and set the background view setBackgroundColor:[UIColor clearColor]]

You can achieve that by having 1 cell per section & set tableview style to Grouped.

If you want to be able to have sections and do not want to create mystery space within your cells, create a collection view instead of a table view. Collection Views can be set to vertical only and one column only = you can also set the minimum line height and interitem spacing. Apple Developer Docs for UICollectionView

Add UIView (childview) to ContentView. Add 10 pixcel spacing from top and bottom to parentView. Add your cell content in childView.

// I found this on internet hope this will help some future seeker
// This method should implement in custom class
// This for give space between row
override var frame: CGRect {
get {
return super.frame
}
set (newFrame) {
var frame = newFrame
frame.origin.y += 4
frame.size.height -= 2 * 5
super.frame = frame
}
}

Related

How to dynamically set a cell position in a UITableView

I am creating a tableView with 4 cells. And the cells must be divided into various size depending on the orientation of the device.
1st column and 2nd column will have the same width, while 3rd column will be the largest of them all and the 4th column will be a smaller than the 3rd column but not smaller than the 1st nor 2nd.
Is there a way to do it dynamically?
Here is the template
I am having trouble in computing the width, here's what I have so far. I haven't created l2,l3 and l4 yet cause I am having a hard time in computing the width of it
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cells" forIndexPath:indexPath];
UIInterfaceOrientation newOrientation = [UIApplication sharedApplication].statusBarOrientation;
UILabel *typeLabel = [[UILabel alloc] init];
if (cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cells"];
}
if(newOrientation == UIInterfaceOrientationLandscapeLeft || newOrientation == UIInterfaceOrientationLandscapeRight)
{
l1 = [[UILabel alloc] initWithFrame:CGRectMake((self.tableView.bounds.size.width/15+20), 50, self.tableView.bounds.size.width/12, 21)];
}
else
{
l1 = [[UILabel alloc] initWithFrame:CGRectMake((self.tableView.bounds.size.width/15+50), 50, self.tableView.bounds.size.width/12, 21)];
}
[cell.contentView l1];
[cell.contentView l2];
[cell.contentView l3];
[cell.contentView l4];
return cell;
}
Create a custom TableView Cell named "CustomCell". You can create it using new File with xib option.
CustomCell.h
#interface CustomCell : UITableViewCell
#end
CustomCell.m
#implementation MessagesTableViewCell
//perform your custom implementation here.
#end
CustomCell.xib
Adjust the labels in the cell in the user interface using auto-layout. You can add 4 labels as you need with first 2 labels having a constant width and last one with the width you want and let the center(3rd) label stretch across 2nd label and 4th label. It will help you manage the UI in much easier way. Auto-Layout is a feature which helps to build content for different sizes. You can find dynamic table view cell using auto layout at https://www.sitepoint.com/self-sizing-cells-uitableview-auto-layout/
Using it in your TableView Class
static NSString *cellIdentifier = #"CustomCell";
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
return cell;
}
I hope this helps you.
Updated code implementation with programmatic computation and Orientation change
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/////////////////////////Programatic Implementation///////////////////////////////////
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell==nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) {
//orientation is Portrait
long widthForL1L2 = tableView.frame.size.width * .10;
long widthForL3 = tableView.frame.size.width * .60;
long widthForL4 = tableView.frame.size.width * .20;
UILabel *l1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, widthForL1L2, cell.frame.size.height)];
l1.backgroundColor = [UIColor redColor];
[cell addSubview:l1];
UILabel *l2 = [[UILabel alloc] initWithFrame:CGRectMake(widthForL1L2, 0, widthForL1L2, cell.frame.size.height)];
l2.backgroundColor = [UIColor yellowColor];
[cell addSubview:l2];
UILabel *l3 = [[UILabel alloc] initWithFrame:CGRectMake(l2.frame.origin.x+widthForL1L2, 0, widthForL3, cell.frame.size.height)];
l3.backgroundColor = [UIColor greenColor];
[cell addSubview:l3];
UILabel *l4 = [[UILabel alloc]initWithFrame:CGRectMake(l3.frame.origin.x+widthForL3, 0, widthForL4,cell.frame.size.height)];
l4.backgroundColor = [UIColor blueColor];
[cell addSubview:l4];
}else{
//orientation is Landscape
//perform the same calculation as above or modify it according to your needs in landscape orientation.
}
return cell;
}
Do not forget to include this function of orientation change. This function calls table reload when phone orientation changes.
//Available iOS version >=8.0
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
//Reload the tableview on orientation change, to match the new width of the table.
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[self.tableView reloadData];
} completion:nil];
}

UITableView subview inside UITableViewCell won't display

I'm trying to create a UITableview, where each cell contains another UITableView. It's basically a list of 2-3 rows, where each row then has a sublist of 2-3 rows inside.
The main ViewController behaves just like any other TableViewController, and inside the cellForRowAtIndexPath, it attempts to add a SubTableViewController.view with a dynamic height. The SubTableViewController is the second tableview and each has their own Datasource.
The problem I'm running into is the SubTableViewController appears to render properly using the debugger, with the correct data and number of cells, but it simply isn't appearing when rendering. I noticed it has a contentSize height of "0" in its ViewDidAppear, despite having 2+ rows produced with height. The project uses AutoLayout but the SubTableViewController's frame is set programmatically when added.
Any ideas what I can do to get something to appear here?
Structure of Data (periods are the subTable)
[{name:"activity 1",
periods:[{name:"period1",desc:"desc1"},
{name:"period2",desc:"desc2"},
{name:"period3",desc:"desc3"}
]
},
{name:"activity 2",
periods:[{name:"period1",desc:"desc1"},
{name:"period2",desc:"desc2"},
{name:"period3",desc:"desc3"}
]
}]
ViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_data count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
UIImageView *imageView = (UIImageView*)[cell viewWithTag:1];
UIView *subTableView = (UIView*)[cell viewWithTag:3];
return imageView.frame.size.height + subTableView.frame.size.height + 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"tableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
ActivityModel *model = _data[indexPath.row];
UILabel *nameLabel = (UILabel*)[cell viewWithTag:2];
nameLabel.text = model.name;
UIView *internalView = (UIView*)[cell viewWithTag:10];
SubTableViewController *subTableViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SubTableViewController"];
subTableViewController.activityModel = model;
subTableViewController.view.tag = 3;
subTableViewController.view.frame = CGRectMake(0,
60,
internalView.frame.size.width,
subTableViewController.view.frame.size.height);
[internalView addSubview:subTableViewController.view];
[internalView bringSubviewToFront:subTableViewController.view];
[subTableViewController.tableView reloadData];
return cell;
}
SubTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
int height = 0;
for (int section = 0; section < [self numberOfSectionsInTableView:_tableView]; section++){
for(int row = 0; row < [self tableView:_tableView numberOfRowsInSection:section]; row++){
height += [self tableView:_tableView heightForRowAtIndexPath:[NSIndexPath indexPathForItem:row inSection:section]];
}
}
CGRect tableFrame = self.tableView.frame;
tableFrame.size.height = height;
self.tableView.frame = tableFrame;
CGRect viewFrame = self.view.frame;
viewFrame.size.height = height;
self.view.frame = viewFrame;
[self.view bringSubviewToFront:_tableView];
// [self.tableView layoutIfNeeded];
// [self.tableView setNeedsDisplay];
// [self.tableView reloadData];
// _tableView.contentSize = CGSizeMake(600, 52);
self.view.backgroundColor = [UIColor redColor];
self.tableView.backgroundColor = [UIColor blueColor];
self.tableView.hidden = NO;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_activityModel.periods count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
UILabel *nameLabel = (UILabel*)[cell viewWithTag:3];
UITextView *textView = (UITextView*)[cell viewWithTag:5];
float textViewHeight = [textView.text sizeWithFont:[UIFont systemFontOfSize:13] constrainedToSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 40, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping].height;
return nameLabel.frame.size.height + textViewHeight + 20;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"tableViewCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
PeriodModel *model = _activityModel.periods[indexPath.row];
UILabel *nameLabel = (UILabel*)[cell viewWithTag:3];
UILabel *durationLabel = (UILabel*)[cell viewWithTag:4];
UITextView *textView = (UITextView*)[cell viewWithTag:5];
nameLabel.text = model.name;
durationLabel.text = [NSString stringWithFormat:#"%d minutes", (int)(model.durationSeconds/60)];
textView.text = model.description;
textView.textContainerInset = UIEdgeInsetsZero;
textView.textContainer.lineFragmentPadding = 0;
textView.scrollEnabled = NO;
CGRect frame = textView.frame;
frame.size.height = [textView.text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:CGSizeMake(cell.contentView.frame.size.width, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping].height;
textView.frame = frame;
return cell;
}
Simulator Image. The title is the outer UITableCell, and below it in red is the added SubTableViewController.view. The UITableView should cover the red, but is not appearing at all here. It is not hidden, underneath, etc.
Do not put a table view inside your cells.
There is little benefit to doing this for your described use. Use sections and rows. Each section would be your current cell. And each row in that section would be a row from your current embedded table view.
Further, if your internal table views had differing sizes you would be needing to calculate all of the internal cell heights for each external cell. That is exactly what happens with sections and rows, but you as the developer only need to worry about the rows and UITableView will handle the section sizing.

UITableView cell contents not displayed properly

I use auto layout and want to display UITableView with custom cell that has a UITextView with variable content.
Cells are displayed as shown below. For chat message, when cell is first displayed only 2-3 characters are displayed in a single line and next characters are forced to go to next line. But when I scroll tableView so that these cells are not visible and scroll back to make them visible (I do this so that when they are visible again cellForRowAtIndexPath: method is called again to render the cell), they render the cell properly as shown in second image.
Code :
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [chatData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
RS_User *user = [[RS_User alloc]init];
chatCell *cell = (chatCell *)[tableView dequeueReusableCellWithIdentifier:CHAT_CELL_IDENTIFIER];
NSUInteger row = indexPath.row;
cell.chatCellBackground.image = nil;
NSString *chatText = [[chatData objectAtIndex:row] objectForKey:TEXT]; // get text string(message) from array
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
UIFont *font = [UIFont systemFontOfSize:FONT_SIZE];
cell.textString.font = [UIFont fontWithName:FONT_NAME size:FONT_SIZE]; // set text font
cell.textString.text = chatText;
// set text
CGSize size = [cell.textString.text sizeWithFont:cell.textString.font constrainedToSize:CGSizeMake(SET_WIDTH, MAXFLOAT) lineBreakMode:NSLineBreakByCharWrapping];
cell.textString.frame = ...;
[cell.textString sizeToFit];
NSDate *theDate = [[chatData objectAtIndex:row] objectForKey:DATE];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:DATE_FORMAT];
NSString *timeString = [formatter stringFromDate:theDate];
cell.timeLabel.text = timeString; // set timeLabel to display date and time
cell.timeLabel.font = [UIFont fontWithName:FONT_NAME size:SMALL_FONT_SIZE];
cell.userLabel.text = #"Name";//[[chatData objectAtIndex:row] objectForKey:NAME]; // set userLabel to display userName
CGSize size1 = [cell.userLabel.text sizeWithFont:font constrainedToSize:CGSizeMake(SET_WIDTH, MAXFLOAT) lineBreakMode:NSLineBreakByCharWrapping];
// check cell contains sender name or receiver name
if (thisCellIsForSender)
{
// Set bubble for sender
cell.chatCellBackground.image = [[UIImage imageNamed:#"bubbleMine.png"] stretchableImageWithLeftCapWidth:STRETCHED_WIDTH topCapHeight:STRETCHED_HEIGHT];
cell.chatCellBackground.frame = ...;
}
else
{
// set bubble for receiver
cell.chatCellBackground.image = [[UIImage imageNamed:#"bubbleSomeone.png"] stretchableImageWithLeftCapWidth:STRETCHED_WIDTH topCapHeight:STRETCHED_HEIGHT];
cell.chatCellBackground.frame = ...;
}
[cell setNeedsLayout];
[cell layoutIfNeeded];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
RS_User *user = [[RS_User alloc]init];
chatCell *cell = (chatCell *)[tableView dequeueReusableCellWithIdentifier:CHAT_CELL_IDENTIFIER];
NSUInteger row = indexPath.row;
cell.chatCellBackground.image = nil;
NSString *chatText = [[chatData objectAtIndex:row] objectForKey:TEXT]; // get text string(message) from array
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
UIFont *font = [UIFont systemFontOfSize:FONT_SIZE];
cell.textString.font = [UIFont fontWithName:FONT_NAME size:FONT_SIZE]; // set text font
cell.textString.text = chatText;
// set text
CGSize size = [cell.textString.text sizeWithFont:cell.textString.font constrainedToSize:CGSizeMake(SET_WIDTH, MAXFLOAT) lineBreakMode:NSLineBreakByCharWrapping];
cell.textString.frame = ...;
[cell.textString sizeToFit];
NSDate *theDate = [[chatData objectAtIndex:row] objectForKey:DATE];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:DATE_FORMAT];
NSString *timeString = [formatter stringFromDate:theDate];
cell.timeLabel.text = timeString; // set timeLabel to display date and time
cell.timeLabel.font = [UIFont fontWithName:FONT_NAME size:SMALL_FONT_SIZE];
cell.userLabel.text = [[chatData objectAtIndex:row] objectForKey:NAME]; // set userLabel to display userName
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
CGSize size1 = [cell.userLabel.text sizeWithFont:font constrainedToSize:CGSizeMake(SET_WIDTH, MAXFLOAT) lineBreakMode:NSLineBreakByCharWrapping];
// check cell contains sender name or receiver name
if (thisCellIsForSender)
{
// Set bubble for sender
cell.chatCellBackground.image = [[UIImage imageNamed:#"bubbleMine.png"] stretchableImageWithLeftCapWidth:STRETCHED_WIDTH topCapHeight:STRETCHED_HEIGHT];
cell.chatCellBackground.frame = ...;
}
else
{
// set bubble for receiver
cell.chatCellBackground.image = [[UIImage imageNamed:#"bubbleSomeone.png"] stretchableImageWithLeftCapWidth:STRETCHED_WIDTH topCapHeight:STRETCHED_HEIGHT];
cell.chatCellBackground.frame = ...;
}
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));
[cell setNeedsLayout];
[cell layoutIfNeeded];
return cell.bounds.size.height;
}
UPDATE : I could solve some of the issues from coverback's answer. Still cell is not laid out correctly. I am adding photos for constraints of each UI object in cell.
User name :
Time stamp :
Chat message :
Bubble image :
Cell Layout :
Cell height in cellForRowAtIndexPath: is always 100 even though I return different value from heightForRowAtIndexPath: method. Cell height in storyboard is 100.
Chat message in third cell is clipped from bottom.
Time stamps and chat message labels are some time not aligned properly to each other even though both have constraint vertical spacing from username label.
Username label in third cell is vanished.
Do you see anything wrong in constraints? You can ask me if analyzing constraints is difficult.
Combining the answers by thandasoru and coverback solved my issue. Below is the code I use.
I added below method in custom UITableViewCell's class.
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat maxTextWidth = [UIScreen mainScreen].bounds.size.width * 0.40;
self.userLabel.preferredMaxLayoutWidth = maxTextWidth;
self.chatMessage.preferredMaxLayoutWidth = maxTextWidth;
self.timeLabel.preferredMaxLayoutWidth = self.timeLabel.frame.size.width;
[super layoutSubviews];
}
UITableView datasource methods :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell * cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"customCellId"];
// Set all label's text and image to ImageView
...
// Update layout
[cell setNeedsLayout];
[cell layoutIfNeeded];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCell * cell = (customCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath];
NSString * userName = cell.userLabel.text;
NSString * chatText = cell.chatMessage.text;
// Get bounding rect of userName label
CGRect userNameFrame = [userName boundingRectWithSize:CGSizeMake(maxLabelWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:cell.userLabel.font} context:nil];
// Get bounding rect of chatMessage label
CGRect chatTextFrame = [chatText boundingRectWithSize:CGSizeMake(maxLabelWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:cell.chatMessage.font} context:nil];
// Calculate cell height from its contents
height = userNameFrame.size.height + chatTextFrame.size.height + PADDING_ABOVE_TOP_LABEL + DISTANCE_BETWEEN_TWO_LABELS + PADDING_BELOW_BOTTOM_LABEL;
return height;
You can determine the cell height dynamically so that the text appears on one line. I've given CGSize(320,568) as bounds. But you can change the size as you see fit
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *chatText = [[chatData objectAtIndex:row] objectForKey:TEXT];
CGRect frame = [chatText boundingRectWithSize:CGSizeMake(320,568) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:[UIFont systemFontOfSize:18.0f]} context:nil];
return frame.height; //returns cell's height after calculating the area that text needs
}
You are setting the frame of the text and calling sizeToFit:
CGSize size = [cell.textString.text sizeWithFont:cell.textString.font constrainedToSize:CGSizeMake(SET_WIDTH, MAXFLOAT) lineBreakMode:NSLineBreakByCharWrapping];
cell.textString.frame = ...;
[cell.textString sizeToFit];
This will not be working with autolayout. You need to remove setting the frame and sizeToFit completely, same goes for all other frame being set directly. If things don't work after that, it would mean some constraints are not correct. But mixing approaches always breaks layout.
For UILabels, make sure to also set preferredMaxLayoutWidth to label's width, otherwise text may not wrap correctly:
- (void)layoutSubviews
{
[super layoutSubviews];
self.label.preferredMaxLayoutWidth = self.label.frame.size.width;
[super layoutSubviews];
}
Also, your height calculating method should not just do same thing as cellForRowAtIndexPath:, if you want to use the same code, just call that other method to get a cell.

How to Implement DataSheet

I want to implement data sheet to display history of user. I want to implement that design like this:
But I dont know how to do that...Can anyone please help me
Edit:
Add the horizontal line at the specific position and the label at the position and it will look like this.
Create a tableview and than in cellForRowAtIndexPath method add this code..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *SimpleTableIdentifier;
UITableViewCell * cell;
SimpleTableIdentifier = #"SimpleTableIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier: nil];
if(cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier];
UILabel * numLbl = [[UILabel alloc] initWithFrame:CGRectMake(0,5,33,30)];
numLbl.text = #"1";
[numLbl setFont:[UIFont fontWithName:#"Helvetica" size:10.0]];
numLbl.backgroundColor = [UIColor clearColor];
[cell addSubview:numLbl];
UILabel * nameLbl = [[UILabel alloc] initWithFrame:CGRectMake(30,5,50,30)];
nameLbl.text = #"john%Lakeview";
[nameLbl setFont:[UIFont fontWithName:#"Helvetica" size:10.0]];
nameLbl.backgroundColor = [UIColor clearColor];
[cell addSubview:nameLbl];
//create a hoizontal separator in cell to display it like column
UIView* hSeparatorview1 = [[UIView alloc] initWithFrame:CGRectMake(25, 0, 1, 30)];
hSeparatorview1.backgroundColor = [UIColor blackColor];
hSeparatorview1.tag = 1;
[cell addSubview:hSeparatorview1];
UIView* hSeparatorview2 = [[UIView alloc] initWithFrame:CGRectMake(85, 0, 1, 30)];
hSeparatorview2.backgroundColor = [UIColor blackColor];
hSeparatorview2.tag = 2;
[cell addSubview:hSeparatorview2];
}
return cell;
}
//this method is used to set the hight of the tableview cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
return 30;
}
I have created it for only two label and two horizontal view but you can create as many as you like.
And yes dot forget to place this code in didSelectRowAtIndexPath otherwise horizontal view will disappear when user click the cell.
- (void)tableView:(UITableView *)atableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//get the cell which is selected
UITableViewCell *selectedCell = [atableView cellForRowAtIndexPath:indexPath];
//set cell horizontal saparator view color of selected cell bcoz when cell selected all view color is gone
UIView *hSeparatorview1=[selectedCell viewWithTag:1];
hSeparatorview1.backgroundColor = [UIColor blackColor];
UIView *hSeparatorview2=[selectedCell viewWithTag:2];
hSeparatorview2.backgroundColor = [UIColor blackColor];
}
Better to try with Custom tableview Cell for text,and UIViews for lines.I'm also done the same in my app.

How to create UITableView like GRID in landscape mode?

I wanna create the uitableview like this image . loading data from server and assigning the values to columns of Row. I saw the link of stack, but not helpful to me.
UPDATE
My code: -
#pragma mark UITableViewDelegate methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return [modelArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
}
cell.selectionStyle = UITableViewCellSelectionStyleGray;
// Configure the cell...
RankModel *model = [modelArray objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%# %# %# %# %# %#", model.level, model.name, model.score, model.rightAnswersCount, model.currentRank, model.country];
return cell;
}
but I wanna display like the given image. so please help me to overcome this problem. thanks in advance.
Well this will require a bit more code than the method you present.
My suggestion is you could create a UILabel for each of your fields, instrad of using a single NSString. Don't use cell.textLabel, but rather add your content on cell.contentView and then you can manage each label's color, background color and labels' sizes. The "grid" look can be rendred by assigning a white color to contentView and assigning a green color for example to each label's background. For example, after your cell is created :
cell.contentView.backgroundColor = [UIColor clearColor];
UILabel* aLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 0.0, 100, 44)];
aLabel.tag = indexPath.row;
aLabel.textAlignment = UITextAlignmentLeft;
aLabel.textColor = [UIColor whiteColor];
aLabel.text = #"Test";
aLabel.backgroundColor = [UIColor greenColor];
[cell.contentView addSubview:aLabel];
[aLabel release];
Start your next label at 201 or more to leave an impression of a white vertical line.
Keep the row index in the tag so you can manage alternate colors in :
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell
*)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0 || indexPath.row%2 == 0) {
// use light green, get access to the labels via [cell.contentView viewWithTag:indexPath.row]
} else {
// use dark green
}
}
Hope this helps.

Resources