How to display values from two tables in uitableviewcell - ios

I'm beginner of Parse.com BaaS. I'm thinking about how to display in one UITableViewCell data from two tables which are connected by pointer. I've got a table named "PackageItems" which contain columns such as:- objectId, packageId, productId, price. In the second table named "SIZES", I store data with attributes like:- objectId, packageItemsId, quantity and sizeTypeId. In the third table named "SIZE_TYPES", I have a columns named:- objectId & typeName. I connect these three tables by pointers in SIZES table like below: packageItemsId -> POINTER -> target class-> PACKAGE_ITEMS sizeTypeId -> POINTER -> target class -> SIZE_TYPES
After that I create a query which return as result every Sizes connected to PackageItems by Pointer packageItemsId.
-(PFQuery *)queryForTable
{
PFQuery *query = [PFQuery queryWithClassName:#"Size"];
PFObject *packagedItem = [PFObject objectWithoutDataWithObjectId:#"SxtIpSJ64t"];
[query whereKey:#"packageItemsId" equalTo:packagedItem];
}
In the cellForRowAtIndexPath method, I display quantity from Sizes table like below in the UITextField and also I try to display typeName from table SIZE_TYPES
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object{
static NSString *simpleTableIdentifier = #"PackageCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell==nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UILabel *sizeLabel = [[UILabel alloc]init];
sizeLabel.text = #"HERE I WOULD LIKE TO DISPLAY VALUE OF SIZE TYPE"
sizeLabel.frame = CGRectMake(20,5,50,34);
[cell.contentView addSubview:sizeLabel];
UITextField *quantityField = [[UITextField alloc]initWithFrame:CGRectMake(245, 5, 55, 34)];
quantityField.borderStyle = UITextBorderStyleRoundedRect;
quantityField.keyboardType = UIKeyboardTypeNumberPad;
quantityField.textAlignment = NSTextAlignmentRight;
quantityField.text = [object objectForKey:#"quantity"];
[cell.contentView addSubview:quantityField];
UILabel *quantityLabel = [[UILabel alloc]init];
quantityLabel.textAlignment = NSTextAlignmentRight;
quantityLabel.text = #"Quantity:";
quantityLabel.frame = CGRectMake(170, 5, 70, 34);
[cell.contentView addSubview:quantityLabel];
}
return cell;
}
I know that the query can return only value from one class. I also tried to create second method that returned SIZE_TYPES but it seems to me that I'm doing it wrong. I've read that the charging of the two table can be done by using the method 'include' but do not really know how to go about it. I also heard about cloud code. Perhaps I should use a relationship and a little change my database schema. Please for any sensible solution.

In your case core data maybe your best choice, checkout this one core data programming guide
and then you can try to use NSFetchRequest and NSPredicate to query the database, that will
give you back a NSArray as return type, then you can sort the result and display them based on
the index.

Related

How can I set a variable in viewForHeaderInSection, and then use it in cellForRowAtIndexPath?

In my table's viewForHeaderInSection, I'm setting the variable _searchTerm, using the section index like so:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 21)];
headerView.backgroundColor = [UIColor colorWithRed:0.949 green:0.949 blue:0.949 alpha:1];
_searchTerm = [[[[_matchCenterData objectAtIndex:section] objectForKey:#"Top 3"] objectAtIndex:0]objectForKey:#"Search Term"];
return nil;
}
For each section, I want to use its respective _searchTerm variable in cellForRowAtIndexPath like so:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//load top 3 data
NSDictionary *currentSectionDictionary = _matchCenterData[indexPath.section];
NSArray *top3ArrayForSection = currentSectionDictionary[#"Top 3"];
//... code removed to brevity
// title of the item
cell.textLabel.text = _searchTerm;
}
This doesn't seem to be working, the cells textLabel is showing up as blank. Is it possible to use a variable from viewForHeaderInSection in cellForRowAtIndexPath, and if so, what am I doing wrong?
Not directly answer your question, but you could achieve the result that you want by assigning cell.textLabel.text to your data source.
cell.textLabel.text = [[[[_matchCenterData objectAtIndex:indexPath.section] objectForKey:#"Top 3"] objectAtIndex:0]objectForKey:#"Search Term"];
now, the possible reason that your cell.textLabel.text is blank, is that because cellForRow method is called first before viewForHeaderInSection
First, consider that anything you use in cellForRowAtIndexPath that varies as a function of indexPath as part of your datasource. Second, don't initialize datasource data viewForHeader. Do so in the same place you initialize the rest of the data (the rest of _matchCenterData)
So, if you have:
#property(strong,nonatomic) NSArray *matchCenterData;
Then also have...
#property(strong,nonatomic) NSArray *searchTerms; // notice the plural name
Where you have:
self.matchCenterData = // whatever
Then also have (in pseudo code)...
for (each section in self.matchCenterData) {
[self.searchTerms addObject:the thing you were setting in viewForHeader]
Now, your cellForRowAtIndexPath, can behave properly with respect to this additional datasource data...
cell.textLabel.text = self.searchTerms[indexPath.section];
Incidentally, an better datasource might include the sectional information in the matchCenterData, rather than the slightly hackier "parallel array" idea I've proposed here.
Even more incidentally, notice how I declare a property named "foo", then refer to it as self.foo, not _foo. With just a few exceptions, that's a practice you should adopt, too.

Parse Event Title from Event Kit

So, I would like to read in my array of events from a calendar I am subscribed to.
The events all have a similar format, for example with two modules, 'Meaning of Life' and 'Running long distances':
Talk: Meaning of Life
Talk: Running long distances
Talk: Meaning of Life
Talk: Meaning of Life
Talk: Running long distances
I would like to be able to use something like
[[event.title componentsSeparatedByString:#"Talk: "] objectAtIndex:i];
So that in my table view I can have a 'Meaning of life' cell and a 'Running long distances' one. The idea would then be to select one and you could see all the 'Talks' for that module. There are other categories too like 'Workshops' and 'Practicals'.
Currently my code to just display all the events is as follows (ignoring the getting events of selected calendar and producing an array titled arrEvents)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TableIDCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"TableIDCell"];
}
// Get each single event.
EKEvent *event = [self.arrEvents objectAtIndex:indexPath.row];
// Set its title to the cell's text label.
cell.textLabel.text = event.title;
// Get the event start date as a string value.
NSString *startDateString = [self.appDelegate.eventManager getStringFromDate:event.startDate];
// Get the event end date as a string value.
NSString *endDateString = [self.appDelegate.eventManager getStringFromDate:event.endDate];
// Add the start and end date strings to the detail text label.
cell.detailTextLabel.text = [NSString stringWithFormat:#"%# - %#", startDateString, endDateString];
if (indexPath.row%2 == 0) {
UIColor *altCellColor = [UIColor colorWithWhite:0.7 alpha:0.1];
cell.backgroundColor = altCellColor;
}
return cell;
}
Thanks for taking the time to read :)
I sorted it in the end by modifying the arrEvents in the class where it is generated. I was able to check if it contained string "Talk: " and them remove that bit and also check if arrEvents already contained a title and then not to add duplicates.

Filter Array into sections

I am building an IOS app based on data within an array - I'm struggling with filtering data into rows - a snippet of my array is as follows -
ARRAY Data / Array -
sightsObject *sight2 = [[sightsObject alloc] initWithsiteTitle:#"The Beatles Homes" siteSection:#"beatles" siteType:#"Take a glimpse of the fab 4's childhood homes.." siteSubTitle:#"" siteDescription:#"" siteMapUrl:#"" sitePic:#"fabs"];
sightsObject *sight3 = [[sightsObject alloc] initWithsiteTitle:#"The Beatles Gig Venues" siteSection:#"beatles" siteType:#"" siteSubTitle:#"Its not all about the Cavern..." siteDescription:#"" siteMapUrl:#"" sitePic:#"fabs"];
sightsObject *sight4 = [[sightsObject alloc] initWithsiteTitle:#"The Beates Locations" siteSection:#"beatles" siteType:#"" siteSubTitle:#"Stawberry Fields, Penny Lane, Palm House..." siteDescription:#"" siteMapUrl:#"docks" sitePic:#"fabs"]
sightsObject *sight5 = [[sightsObject alloc] initWithsiteTitle:#"Albert Dock" siteSection:#"dock" siteType:#"" siteSubTitle:#"" siteDescription:#"" siteMapUrl:#"" sitePic:#""];
sightsObject *sight6 = [[sightsObject alloc] initWithsiteTitle:#"Keiths Wine Bar" siteSection:#"Restaurants" siteType:#"" siteSubTitle:#"Classic Eatery on Lark Lane" siteDescription:#"" siteMapUrl:#"" sitePic:#""];
self.sightsArray = [NSArray arrayWithObjects: sight2, sight3, sight4, sight5, sight6,nil];
SightsObject.H
The Header for the SightsObject os as follows -
#import <Foundation/Foundation.h>
#interface sightsObject : NSObject
#property(strong)NSString *siteTitle;
#property(strong)NSString *siteSection;
#property(strong)NSString *siteType;
#property(strong)NSString *siteSubTitle;
#property(strong)NSString *siteDescription;
#property(strong)NSString *siteMapUrl;
#property(strong)UIImage *sitePic;
-(id)initWithsiteTitle:( NSString *)siteTitleD siteSection:(NSString *)siteSectionD siteType:(NSString *)siteTypeD siteSubTitle:(NSString *)siteSubTitleD siteDescription:(NSString *)siteDescriptionD siteMapUrl:(NSString *)siteMapUrlD sitePic:(NSString *)sitePicD;
#end
ROWS
I was unsure how to count the amount of data rows that apply to each section - so this is currently hardcoded -
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 8;
}
FILTERING DATA INTO TABLE CELLS
My issue is that I now dont know how to filter the data into rows - I currently have below (i have two cell types in my tableview) - when run the code displays the relevant data in the correct cells - but repeats the same data for every section - how can I filter it correctly?
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier =#"sightsCell";
static NSString *CellIdentifierH =#"headerCell";
NSString * intro = #"intro";
NSString * ArtNoP = #"lower";
sightsObject *b = [self.sightsArray objectAtIndex:indexPath.row];
tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
UITableViewCell *cell;
if ([b.siteSection isEqualToString:intro]) {
cell= [tableView dequeueReusableCellWithIdentifier:CellIdentifierH forIndexPath:indexPath];
HeaderCell *cellHead = (HeaderCell *)cell;
cellHead.selectionStyle = UITableViewCellSelectionStyleNone;
cellHead.sightsText.text = b.siteTitle;
cellHead.textLabel.backgroundColor=[UIColor clearColor];
return cellHead;
}
else{
cell= [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
sightsCell *cellSights = (sightsCell *)cell;
cellSights.selectionStyle = UITableViewCellSelectionStyleNone;
cellSights.sightsTitle.text = b.siteTitle;
cellSights.sightsSubTitle.text = b.siteSubTitle;
cell.textLabel.backgroundColor=[UIColor clearColor];
return cellSights;
}
}
I'd change what you're doing. Rather than have one array with a big list of items and a static count of the sections I'd have an array which contains sections, and each section would be another array containing the row items. This could either be created manually (your configuration code would change) or automatically (by iterating over your existing sightsArray and running various predicates on it. The choice really depends on how many items you have and how many / where they will come from in the future.
Once you have that, the number of sections is self.sightsArray.count and the number of rows in each section is [self.sightsArray[section] count] and the row for a section is:
sightsObject *b = self.sightsArray[indexPath.section][indexPath.row];
I would also use indexPath.row == 0 as the indication that you should have an intro row because to organise the sections automatically I would keep all of the siteSection values the same for each section.

UITextfield in UITableview with Calendar value

I have a question about populating UITableViewCell with the selected value in calendar. So i have this tableview which is of course created when the view appears, and as i said i also i have this calendar view controller. The main idea is that users can select a date on the calendar, and after that that value should appear in the text field in tableview.
I've have a function that is returning the selected value from the calendars view controller to that other view controller, but after that i can't populate the UITextField with that value.
Any idea or previous similar experience?
Here is the code that is used in the calendar view controller
-(void)giveString:(NSString*)string{
GradesViewController *grades = [[GradesViewController alloc]init];
[grades getString:string];
NSLog(#"String : %#",string);}
and here is the class in that other view in which i want this string value from calendar in my textfield located in tableviewcell
-(void)getString:(NSString*)string{
stringDate = string;
NSLog(#"String: %#",stringDate);}
the both values appear in log...
You are never retaining "string" in [GradesViewController getString:string]
-(void)getString:(NSString*)string {
stringDate = string;
[stringDate retain];
NSLog(#"String: %#",stringDate);
}
Make sure it's released as well in order to ensure that garbage collection will clean it up.
you need to set the stringDate value in cellForRowAtIndexpath, if you are declared that textfield in your tableviewcell cellForRowAtIndexpath. If you are using custom tableviewcell, you need to pass that value to you custome tableView cell class, like how you are calling from CalendarViewController to other ViewController
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellId = #"cellId";
UITableViewCell *tableCell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (tableCell == nil) {
tableCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
UITextField *urlTxtFld = [[UITextField alloc] initWithFrame:CGRectMake(70, 10, 230, 120)];
urlTxtFld.backgroundColor = [UIColor clearColor];
urlTxtFld.text = stringDate // you need to set your text like this
urlTxtFld.autocorrectionType = UITextAutocorrectionTypeNo;
[qrCell addSubview:urlTxtView];
[urlTxtFld release];
}
}

Why does my custom UITableViewCell never change from the prototype?

I have a custom class that extends UITableViewCell. It has two labels and a UISegmentedControl.
Here is the cellForRowAtIndexPath() that I configured. When I inspect "cell" in the debugger it has all the data I'm providing. But somehow that data never gets applied.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
CustomGameCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[CustomGameCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
MyData *my_data = [rows objectAtIndex:indexPath.row];
UILabel *my_date = [[UILabel alloc] init];
my_date.text = my_data.myDate;
[cell setMyDateLabel:my_date];
UILabel *my_question = [[UILabel alloc] init];
my_question.text = my.question;
[cell setMyQuestionLabel:my_question];
UISegmentedControl *my_choices = [[UISegmentedControl alloc]
initWithItems:[NSArray arrayWithObjects:my.firstChoice, my.secondChoice, nil]];
[my_choices setSelectedSegmentIndex:my.choice];
[cell setMyChoiceSegments:my_choices];
return cell
}
The data that I want displayed is currently in an array I create in viewDidLoad() which is accessible to cellForRowAtIndexPath() through the "rows" var.
When I run the code in the simulator I get three rows in the table representing the three elements in the array I created in viewDidLoad(). However, the content of those rows look exactly like what I defined in the storyboard.
What am I missing?
Where are you defining the layout of your cell? In a NIB? In your storyboard? Programmatically in your initWithStyle of CustomGameCell? The implementation details vary a little based upon which approach you use, but you definitely need to either define NIB or prototype cell in your storyboard, or programmatically create the controls, set their frames, perform addSubview so they're included in the cell, etc.
Your code is adding new UILabel objects, not adding them as a subview to anything, doing it regardless if you're using a dequeued cell or not, etc. So there are numerous problems here. To see examples of how you might properly use a custom cell, see Customizing Cells in the Table View Programming Guide. But, like I said, the details vary a bit based upon how you're designing your subclassed UITableViewCell layout, so I hesitate to propose any code until you specify how you're designing your user interface.
You must have added the labels and segmentcontrol in the cells content view of the cell, if not then please do so.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
CustomGameCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[CustomGameCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
MyData *my_data = [rows objectAtIndex:indexPath.row];
cell.myDateLabel.text = my_data.myDate;
cell.myQuestionLabel.text = my.question;
[cell.myChoiceSegments setSelectedSegmentIndex:my.choice];
[cell autorelease];
return cell
}
Also use autorelease for the memory management.

Resources