My problem is little complicated to define for me, even I understand what I am trying to do, I try my best to write this problem to understandable, guide me if I lack anything in question description.
So the problem is that I have a UITableView inside a UITableViewCell, both of UITableViews have custom UITableViewCell classes. Datasource and delegate of both outer an dinner UITableView's are in same class. I am handling the data array like this
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (tableView==self.mainTableView) {
return titleArray.count;
}
return timeArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView==self.mainTableView)
{
MainTableViewCell *cell = [tableView dequeueReusableCellWitentifier:#"cell"];
cell.label.text = [dataArray objectAtIndex:indexPath.row];
return cell;
}
InnerTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
cell.view.backgroundColor = [UIColor greenColor];
return cell;
}
My custom cell's description
Main UITableViewCell cusotm class properties - UILabel (eg.
myLabel),UITableView(inside)
Inside UITableViewCell custom class properties - UIView (eg.
myView)
Now I want to show myView only on that cell when 'myLabel' matches with my array of string object. for eg.
if([myLabel.text isEqualTostring:#"22"]){
cell.myView.backgroundColor = [UIColor blackColor];
}
For eg. if I have 5 views and 2 label, now 2 rows in Main UITableView and 5 rows in inside UITableView but every view should be in the outer cell
only if it matches the myLabel'text.
P.S Don't think about where matching data coming from its not an issue issue of matching data.
As a final conclusion I want to create different row count for each inner UITableView cell.
Did you tried this?
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if( tableView == self.mainTableView )
{
MainTableViewCell *cell = [tableView dequeueReusableCellWitentifier:#"cell"];
cell.label.text = [dataArray objectAtIndex:indexPath.row];
return cell;
}
InnerTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
MainTableViewCell *parentCell = (MainTableViewCell*)cell.superView;
NSIndexPath *parentIndexPath = [self.mainTableView indexPathForCell:parentCell];
NSString *text = [dataArray objectAtIndex:parentIndexPath.row];
if( [text isEqualTostring:#"22"] //your condition goes here
{
cell.view.backgroundColor = [UIColor blackColor];
}
else
{
cell.view.backgroundColor = [UIColor greenColor];
}
return cell;
}
Related
How to create the following UITableView in a VC with 2 Columns? As UITableView only has one column. Is it possible to do it in StoryBoard? How to add shadow, round the corners and add the blurish borders as in the pic? All help or pointer is greatly appreciated.
Edited
How to set the 2 columns in Objective C? I can't find any help over the net especially for objective C. I think both the columns are UILabel.
As for the rows, do I need to set the Prototype Cell to 3 at Story Board?
The 1st column will have static values: NAME, DATE OF BIRTH, LOCATION. The 2nd column will fetch data from an array [John Doe, 06.03.1991, New York]
Do I create a loop to insert the data?
ANSWER
I followed this link and managed to create 2 custom UILabel columns and insert the columns from NSMutableArray
I can't get the following suggested answer to work, the answer suggested that we create an Empty User Interface and then add a Table View Cell and associate it back to the VC. I can't get it to work.
Mine was just creating the 2 labels at the prototype cell at the TableView and then following the link above.
create a customcell and put 7 UILabel first 4 label gives name basic setting,NAME,DOB,LOCATION than remain 3 label set blank and give tham property in cell.h file
#pragma mark tableview delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [yourdataarray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"yourcustomcellname"];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"yourcustomcellname" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
id object = [yourdataarray objectAtIndex:indexPath.row];
if ([object isKindOfClass:[NSMutableArray class]]) {
NSMutableArray *Array = (NSMutableArray *)object;
//your cell property use here for fatch like below
[cell.NAME setText:[NSString stringWithFormat:#"%#",[Array objectAtIndex:i]]];//here i=which index your array contain name data
}
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return yourcustomcellheight;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
refer this tutorial for customcell
https://www.appcoda.com/customize-table-view-cells-for-uitableview/
You need to use custom UITableViewCell, it seems the first column is just a label and the second column is a textfield.
In order to add boundary and add corner
myTableViewCell.contentView.layer.borderColor = [[UIColor grayColor] CGColor];
myTableViewCell.contentView.layer.borderWidth = 1;
myTableViewCell.contentView.layer.cornerRadius = 5.0;
myTableViewCell.contentView.clipsToBounds = YES;
myTableViewCell.contentView.layer.masksToBounds = YES;
check following example as a reference to learn how to create Custom UITableViewCell and use.
https://www.appcoda.com/ios-programming-customize-uitableview-storyboard/
These columns you need to design in UITableViewCell. It can be anywhere of your preference, storyboard or xib.
For storyboard your view will be like this.
you need to add tags for all the components you add into the cell
- (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];
}
...
...
UILabel *label1 = (UILabel *)[cell viewWithTag:100];
label1.text = #"NAME";
UILabel *label2 = (UILabel *)[cell viewWithTag:200];
label2.text = #"John";
...
...
return cell;
}
The same way if you create xib your custom cell should be like this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
StackTableviewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = (stackTableviewCell*)[[[NSBundle mainBundle] loadNibNamed:#"StackTableviewCell" owner:self options:nil] objectAtIndex:0];
}
...
...
label1.text = #"NAME";
label2.text = #"John";
...
...
}
For cell UI
self.lable1.backgroundColor = [UIColor lightGrayColor];
self.lable1.layer.borderColor = [UIColor colorWithRed:169/255.0 green:169/255.0 blue:169/255.0 alpha:0.8].CGColor;
self.lable1.layer.borderWidth = 1;
self.lable1.layer.cornerRadius = 5;
self.lable1.clipsToBounds = YES;
self.lable1.layer.masksToBounds = YES;
I am having this weird issue where my UITableView starts jerking or stuttering when scrolling up, but as soon as I scroll up all the way, it is fine. I am using this table view to hold a chat conversation. I am using a custom cell, and it is only populating text on two labels.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MessagesInfo" forIndexPath:indexPath];
//
// Configure the cell...
WinMessagesInfoCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"MessagesInfo" forIndexPath:indexPath];
if (cell == nil) {
cell = [[WinMessagesInfoCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MessagesInfo"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber *userId = [defaults valueForKey:#"loggedInUserId"];
NSLog(#"Line 791 WinMessageViewController");
if ([self.sender_id objectAtIndex:indexPath.row])
{
if ([[self.sender_id objectAtIndex:indexPath.row] isEqual:userId]){
cell.friendName.textColor = [UIColor blueColor];
cell.friendName.text = #"Me";
}
else
{
cell.friendName.textColor = [UIColor greenColor];
cell.friendName.text = [self.from objectAtIndex:indexPath.row];
}
cell.friendMessage.text = [self.message objectAtIndex:indexPath.row];
}
return cell;
}
Update:
This issue appears to be the height of my cells, if I take out the dynamic cell growth, the issue goes away, but I need them to grow dynamically. I am currently using the following:
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
//minimum size of your cell, it should be single line of label if you are not clear min. then return UITableViewAutomaticDimension;
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
The estimates must be bad. Any advice to get a better estimate? There are two labels in the cell and only one of the labels will change in size.
I have a UITableView that I followed a tutorial on AppCoda, and formatted 2 strings to be displayed in the table that I declared in the ViewController.h. Because my app is parsing a downloaded JSON file, it take a second or two to fill the strings with the variables I want to display. My problem is that it only reloads when the cell reenter the view. What I need to do is reload the methods below when the parsing has finished.
Here are my ViewController.m methods:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_recipies count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:simpleTableIdentifier];
}
cell.backgroundColor = [UIColor clearColor];
[cell.textLabel setTextColor:[UIColor whiteColor]];
cell.textLabel.text = [_recipies objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [_weatherArray objectAtIndex:indexPath.row];
NSLog(#"Updated");
return cell;
}
Calling [self.tableView reloadData] will reload your table view and call tableview: cellForRowAtIndexPath: as well. (If necessary replace self.tableView with whatever variable you're using to store a reference to your table view.)
At the outset I would like to tell that I have researched and tried to follow stackoverflow links such as UISearchDisplayController and custom cell but still the problem persists
I have Search Bar and Search Display controller integrated into my UITableView. The search functionality works fine but the search results cell have the default white cell design and not my custom cell design which is used for the UITableView. Below is my code to make the Search Result's Cell design adapt my custom design.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.searchDisplayController.searchResultsTableView registerClass:[ItemCellTableViewCell class] forCellReuseIdentifier:#"Cell"];
if(!self.document){
[self initDocument];
}
self.filteredItemCatalogArray = [[NSMutableArray alloc]init];
self.itemCatalogTableView.dataSource = self;
self.itemCatalogTableView.delegate = self;
[self.itemCatalogTableView reloadData];
self.itemCatalogTableView.backgroundColor = [UIColor clearColor];
self.itemCatalogTableView.opaque = NO;
self.itemCatalogTableView.bounces = YES;
self.itemCatalogTableView.backgroundView = nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
if(tableView == self.searchDisplayController.searchResultsTableView)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//cell fields customization
cell.backgroundColor = [UIColor clearColor];
cell.opaque = NO;
return cell;
}
else
{
ItemCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//cell fields customization
cell.backgroundColor = [UIColor clearColor];
cell.opaque = NO;
return cell;
}
}
What am I missing here ?
EDITED :
In the if block for search results I changed tableview to self.tableview and it gets the correct custom cell. But it takes the incorrect height which is smaller and so overlaps the rows for search results
In the if block for search results I changed tableview to self.tableview and it get the correct custom cell. But it takes the incorrect height which is smaller and so overlaps the rows for search results
to rectify the height issue I added the following line in viewdidload
self.searchDisplayController.searchResultsTableView.rowHeight =
self.tableView.rowHeight ;
1) If your cell are using a xib file you should add to viewDidLoad (or other method that will be called before tableView delegate)
[yourTableView registerNib:[UINib nibWithtName:#"your_nibName" bunde:yourBunde] forCellReuseIdentifier:#"yourIdentifier"]
also you should use registred identifier for custom cell :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
static NSString *CustomCellIdentifier = #"yourIdentifier";
if(tableView == self.searchDisplayController.searchResultsTableView)
{
// UITableViewCell customization
return cell;
}
else
{
ItemCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier forIndexPath:indexPath];
if (!cell)
cell = [[ItemCellTableViewCell alloc] initWithStyle:yourPreferedStyle reuseIdentifier:CustomCellIdentifier] // or other custom initialization
//put cell fields customization here
return cell;
}
}
If your custom cell is designed using a NIB try this
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:#"YourCellNibName" bundle:Nil] forCellWithReuseIdentifier:#"Cell"];
You have to get a reference of your tableView and then in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
MyCell *cell = (MyCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
...
}
I have a UITableView with one section. All of the cells in that one section have cells that are derived from a subclass of UITableViewCell called PLContactCell.
What I'd like to do is, for the very last row of the table only, not use a PLContactCell. I just want to use a normal UITableViewCell that I can format however I would like. I'd also like to be able to have this cell NOT respond to being tapped.
My initial cellForRowAtIndexPath method is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PLContactCell *cell = [tableView dequeueReusableCellWithIdentifier:[PLContactCell reuseIdentifier]];
if (!cell) {
cell = [PLContactCell reusableCell];
cell.delegate = self;
}
id modelObject = [[sections objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
if ([modelObject isKindOfClass:[NSString class]]) {
[cell configureWithString:modelObject];
} else {
[cell configureWithUser:modelObject];
}
return cell;
}
EDIT
So I tried created a UITableView cell in the XIB file and added the reuse identifier of "newCell" to it. Then I added this code:
if (indexPath.row == [[sections objectAtIndex:indexPath.section] count] - 1) {
NSString *CellIdentifier = #"newCell";
noFormatCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
This doesn't do anything. My question is, how do I access the last row of the section and how do I make it so that that cell it is not a PLContactCell but a UITableView Cell.
If it's always at the end, you might consider using the footer view of the UITableView. You can then keep some extra logic out of your UITableViewDataSource.
If it HAS to be as a cell, you'd have to add an extra row count on your last section, then do an if statement check to watch out for it in your -tableView:cellForRowAtIndexPath: implementation. I would strongly urge you try the footer approach, as it's cleaner and way easier to figure out what you were doing a few months/years from now.
Here's some code. Note you'd need to make another section if you are using grouped style in the UITableView.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == sections.count - 1) //Looking for last section
{
return [sections objectAtIndex:section].count + 1; //Add one to the last section
}
return [sections objectAtIndex:section].count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger row = indexPath.row;
if ((sections.count == indexPath.section) && [sections objectAtIndex:indexPath.section].count == indexPath.row)
{
//Here you would create and return your UITableViewCell
}
PLContactCell *cell = [tableView dequeueReusableCellWithIdentifier:[PLContactCell reuseIdentifier]];
if (!cell) {
cell = [PLContactCell reusableCell];
cell.delegate = self;
}
id modelObject = [[sections objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
if ([modelObject isKindOfClass:[NSString class]]) {
[cell configureWithString:modelObject];
} else {
[cell configureWithUser:modelObject];
}
return cell;
}