UITableView inside UIView - data loads only when scrolling cells outside uitableview - ios

I have a problem using a UITableView inside a UIViewController:
When I start the app the UITableView is shown, but the data from _opponents isn't shown.
When I start scrolling the first cell outside the UITableView, now this cell gets updated.
Also, when I trigger [_topponents reloaddata] manually, the whole UITableView shows the correct data.
What do I have to add or change, so that the data is shown from the beginning?
dataSource and delegate are both connected with the class in the storyboard
Here is my code:
viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
myappdel = (AppDelegate *)[UIApplication sharedApplication].delegate;
self.title = #"New Match";
_lopponent.text = _opponent;
opponents = [[NSMutableArray alloc] init];
NSMutableDictionary *opponent = [[NSMutableDictionary alloc] init];
[opponent setObject:#"opponent A" forKey:#"name"];
[opponent setObject:#"xx matches | xx wins || xx losts" forKey:#"stats"];
[opponent setObject:#"Krems" forKey:#"location"];
NSMutableDictionary *opponent2 = [[NSMutableDictionary alloc] init];
[opponent2 setObject:#"opponent B" forKey:#"name"];
[opponent2 setObject:#"yy matches | yy wins || yy losts" forKey:#"stats"];
[opponent2 setObject:#"Location B" forKey:#"location"];
NSMutableDictionary *opponent3 = [[NSMutableDictionary alloc] init];
[opponent3 setObject:#"opponent C" forKey:#"name"];
[opponent3 setObject:#"zz matches | zz wins || zz losts" forKey:#"stats"];
[opponent3 setObject:#"Location C" forKey:#"location"];
[opponents addObject:opponent];
[opponents addObject:opponent2];
[opponents addObject:opponent3];
[_topponents reloadData];
}
and here my cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"opponentcell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *lopponentname = (UILabel*)[cell viewWithTag:1];
UILabel *lopponentstats = (UILabel*)[cell viewWithTag:2];
UILabel *llocation = (UILabel*)[cell viewWithTag:3];
lopponentname.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"name"];
lopponentstats.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"stats"];
llocation.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"location"];
return cell;
}

I found my fault!
I used to write:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]
but I should use
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
with "forIndexPath"

I think, the trouble is in the cell. Create UITableViewCell subclass.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"opponentcell";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.lopponentname.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.lopponentstats.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"stats"];
cell.llocation.text = [[opponents objectAtIndex:indexPath.row] objectForKey:#"location"];
return cell;
}
Hope it helps you.

Add this after initialisation of cell. For me works properly.
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

I think you are using custom cel and it looks you have trouble in "cellForRowAtIndexPath". If you using .xib, you may find it useful.
static NSString *cellIdentifier = #"opponentcell";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
NSArray *nibObjects =[[NSBundle mainBundle] loadNibNamed:#"CustomTableViewCell" owner:nil options:nil];
for (id currentObject in nibObjects)
{
if ([currentObject isKindOfClass:[CustomTableViewCell class]])
{
cell = (CustomTableViewCell *) currentObject;
}
}
[cell initViewStyles];
}

You need to check for condition when cell is nil..
Initially the cell is nil..
So the data is loading only after scrolling...
Add below lines of code in your cellForRowAtIndexPath delegate method after initializing cell.
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Hope this fixes the issue...

Related

Modifying one cell in CellForRowAtIndexPath changes multiple cells

I have an array of names that I'm showing via tableview. You can select up to a total of 3 names, and you cannot re-select the same names. To do this I implemented the following code in cellForRowAtIndexPath:. When I run the code the names come up fine, but there are multiple red cells with names that I did not select.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSString *sectionTitle = [nameSectionTitles objectAtIndex:indexPath.section];
NSArray *sectionNames = [names objectForKey:sectionTitle];
NSString *name = [sectionNames objectAtIndex:indexPath.row];
cell.textLabel.text = name;
if ([name isEqualToString: self.name1] || [name isEqualToString: self.name2] || [name isEqualToString: self.name3]) {
[cell setUserInteractionEnabled:NO];
cell.backgroundColor = [UIColor redColor];
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Reading a similar problem here, they were saying that it's because the cells are being reused - but if this were true, how is the tableview still displaying the correct names in the correct position?
I tried to simplify the code into this, and still to no avail, there were multiple red cells.
myIP = [NSIndexPath indexPathForRow:0 inSection:0];
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"TableCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSString *sectionTitle = [nameSectionTitles objectAtIndex:indexPath.section];
NSArray *sectionNames = [names objectForKey:sectionTitle];
NSString *name = [sectionNames objectAtIndex:indexPath.row];
cell.textLabel.text = name;
if (indexPath == myIP) {
cell.backgroundColor = [UIColor redColor];
}
return cell;
}
I can post a screenshot if needed. Note: The intended names were correctly labeled with red.
The issue is happening due to cell re-using. When a cell with red background is re-used it'll still be in red background, you are not re-setting it anywhere in your code. You need to put a else case to your if condition used in cellForRowAtIndexPath: method.
if ([name isEqualToString: self.name1] || [name isEqualToString: self.name2] || [name isEqualToString: self.name3])
{
[cell setUserInteractionEnabled:NO];
cell.backgroundColor = [UIColor redColor];
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
[cell setUserInteractionEnabled:YES];
cell.backgroundColor = [UIColor clearColor];
// Other stuffs
}

How to reload data from a specific NSMutableArray into a UITableView

Hi I'm using a web service that returns a JSON document. In that document are several objects, each one containing a value for "STATE" (among others like "ADDRESS", "DISTANCE",etc). This "STATE" value can be either "ARCHIVED" or "ACTIVE". What I want to do is to load the objects with "ARCHIVED" value of "STATE" into the archivedProcessTV and the others to activeProcessTV.
I managed to fill both mutable arrays with the desired data but when the TableViews reload, they reload all the objects into the cells.
Here is what I'm doing on connectionDidFinishLoading:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(#"Entrou no connectionDidFinishLoading");
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
process = [[NSJSONSerialization JSONObjectWithData:data options:0 error:nil] objectForKey:#"GetGesturbeDataJsonResult"];
NSInteger i = 0;
archived = [[NSMutableArray alloc] init];
active = [[NSMutableArray alloc] init];
for (NSObject *array1 in process) {
while (i <= process.count) {
if([[[process objectAtIndex:i] objectForKey:#"STATE" ] isEqualToString:#"ARCHIVED"])
{
[archived addObject:[process objectAtIndex:i]];
i++;
}else
[active addObject:[process objectAtIndex:i]];
i++;
}
}
[activeProcessTV reloadData];
[archivedProcessTV reloadData];
}
Thanks for your help!
EDIT:
-(UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:#"a cell"];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"a cell"];
cell.textLabel.text = [[process objectAtIndex:indexPath.row] objectForKey:#"DISTANCE"];
return cell;
}
You appear to have 2 problems:
tableView:cellForRowAtIndexPath: does not check which table view is asking for data
You don't use your specific array contents to populate the table views, you use [[process objectAtIndex:indexPath.row] objectForKey:#"DISTANCE"]; which contains all data
So, at the start of tableView:cellForRowAtIndexPath: you should have an if statement which checks the atableView parameter and decides which array to use. Then, edit the line which updates the cell text to use that array.
- (UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *sourceArray;
if (atableView == self.activeProcessTV) {
sourceArray = self.active;
} else {
sourceArray = self.archived;
}
UITableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:#"a cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"a cell"];
}
cell.textLabel.text = [[sourceArray objectAtIndex:indexPath.row] objectForKey:#"DISTANCE"];
return cell;
}
Aside: this code:
UITableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:#"a cell"];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"a cell"];
needs to be changed to:
UITableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:#"a cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"a cell"];
}
as currently you're always creating a new cell even if you did get a reusable one back...
In-spite of using sourcearray just pass like that below and check:-
-(UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:#"a cell"];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"a cell"];
}
if ( atableView ==self.activeProcessTV) {
cell.textLabel.text = [[self.activeProcessTV objectAtIndex:indexPath.row] objectForKey:#"DISTANCE"];
}
else{
cell.textLabel.text = [[self.archived objectAtIndex:indexPath.row] objectForKey:#"DISTANCE"];
}
return cell;
}
Note: Pass the correct array count inside numberOfRowsInSection method of UITableView.

How to use to two cell identifiers to sort data?

com documentation, and I am using the PFQueryForTable method with two different tableViewCells to sort my parse objects when they are put into the cells. I am doing this so when the object returns a blank string I can reduce its height to 0. Unfortunately when I do this it does not run like I want to and the blank cells are loaded into the first first cell, and not the one that I want to reduce the height to.
My cellForRowAtIndexPath looks like:
-(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object{
BOOL blank = [[[object objectForKey:#"post"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""];
static NSString *CellIdentifier = #"Cell";
static NSString *Cell2Identifier = #"Cell2";
if (!blank) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
UILabel *label;
label = (UILabel *)[cell viewWithTag:1];
label.text = [object objectForKey:#"post"]; //[object objectForKey:#"post"];
label.textAlignment = NSTextAlignmentCenter;
NSLog(#"posted cell");
return cell;
}
else {
UITableViewCell *cell2 = [tableView dequeueReusableCellWithIdentifier:Cell2Identifier forIndexPath:indexPath];
if (cell2 == nil) {
cell2 = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Cell2Identifier];
}
cell2.textLabel.text = [object objectForKey:#"post"];
NSLog(#"posted cell2");
return cell2;
}
}
Can someone please point me in the right direction?
Thank you.
OK, from your comment you are currently creating a query like this...
- (PFQuery *)theQuery
{
PFQuery *posts = [PFUser query];
[posts whereKey:#"location" nearGeoPoint:self.myLocation withinKilometers:10.0];
[posts includeKey:self.textKey];
return posts;
}
So all you need to do is add another where condition to it...
[posts whereKey:#"theText" notEqualTo:#""];
This will stop blank text posts from being sent down.

Displaying NSArray in UITableView (iOS)

I want to display in UITableView array like:
(
1,
{
date = 1351876762;
ncom = 0;
nid = 11739814;
"read_ncom" = 0;
text = "<div class=\"wikiText\"><!--4-->New note text </div>";
title = lol;
uid = 3795852;
}
)
Cells should have a label with "title" from this array.
How can I make that?
P.S.:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *textCell = [[array objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.textLabel.text = textCell;
return cell;
}
returns signal SIGABRT.
Thanks.
[EDIT]
Your array seems to be weird. Try following and let me know the result.
NSString *textCell = [[array objectAtIndex:1] objectForKey:#"title"];
You should have cell with identifier "Cell" in your table (if you have storyboard) or create this cell manually
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[array objectAtIndex:1] objectforkey:#"title"];
try the above code
Replace this :
NSString *textCell = [[[array objectAtIndex:indexPath.row] objectForKey:#"1"]objectForKey:#"title"];

Adding Cells to UITableView from array

I pass an array called userArray which stores another array with strings. This is what I have so far but I know it's wrong. Can someone point me in the right direction?
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
}
//Set Up Cell
DataSingleton *sharedData = [DataSingleton sharedData];
for (NSArray *array in sharedData.usersArray){
cell.primaryLabel.text = [array objectAtIndex:1];
cell.secondaryLabel.text = [array objectAtIndex:2];
cell.profileImage = [UIImage imageNamed:#"111-user.png"];
return cell;
}
}
cellForRowAtIndexPath is a UITableViewDataSource method, and it asks the data for single cell only. So, you have to remove a loop, and set up a single cell at once, using indexPath.row as an array index in your DataSingleton
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
}
//Set Up Cell
DataSingleton *sharedData = [DataSingleton sharedData];
NSArray *array = [sharedData.usersArray objectAtIndex:indexPath.row];
cell.primaryLabel.text = [array objectAtIndex:1];
cell.secondaryLabel.text = [array objectAtIndex:2];
cell.profileImage = [UIImage imageNamed:#"111-user.png"];
return cell;
}
Also, you should implement tableView:numberOfRowsInSection: to return [[[DataSingleton sharedData] usersArray] count]

Resources