UIPickerView dynamically populate the data from external XML file - iphone

is it possible to populate the UIPickerView data dynamically from external XML file.
For example, I will have TextA, TextB and TextC in my picker view and I have the same in my XML file in remote server. I have successfully developed reading the XML data from remote server and displaying the text (they were title and url) in my tableview. But now I am trying to populate my UIPickerView data from my XML file. The main purpose of this is to dynamically control the UIPickerView data from my XML file.
Is there anyway to make this happen?

You can parse XMl files with NSXMLParser. It's an event driven parser, so you have to set up a delegate to handle all the callbacks and create your arrays and dictionaries from the parsed nodes.
You could also use a class like XMLReader. This allows you to simply pass your xml as an NSData or NSString object and get a parsed NSDictionary. You can then use that to populate the UIPickerView.
It's a bit inconvenient though and it would be a better choice to use .plist files, if you can. Of course that's not an option, if you want to access the same information from other platforms too.
Then, all you would have to do after downloading the file is:
NSArray *onlineList = [plistAsString propertyList];
Or if you download the file onto disk:
NSArray *onlineList = [[NSArray alloc] initWithContentsOfFile:pathToPlistFile];
// release if not using ARC.

I have done the following to display the title and url in one of my apps. I want the same to populate the picker data instead of table cell:
This is a link of one of my apps which demonstrates the implementation of the following code:
urlString = #"http://jeewanaryal.web44.net/iPhoneXML/nepaliMoviesNews.xml";
data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
dict = [XMLReader dictionaryForXMLData:data error:nil];
newsItems = [[NSMutableArray alloc] initWithArray:[[[dict objectForKey:#"list"] objectForKey:#"lists"] objectForKey:#"news"]];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell= [[CustomCell alloc] initWithFrame:CGRectMake(0, 0, 300, 60)];
// Default to no selected style and not selected
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// Set the image for the cell
[cell setTheImage:[UIImage imageNamed:[NSString stringWithFormat:#"Arrow3.png"]]];
NSMutableArray *temp = [[NSMutableArray alloc] init];
for (NSDictionary *fruitDict in newsItems) {
//UILabel *songTitle = [[UILabel alloc] initWithFrame:CGRectMake(40, 200, 300, 40)];
[temp insertObject:[NSString stringWithFormat:#"%#",[[fruitDict objectForKey:#"title"] objectForKey:#"text"]]
atIndex:0];
//cell.textLabel.text = [NSString stringWithFormat:#"%#",[[fruitDict objectForKey:#"title"] objectForKey:#"text"]];
//[self.view addSubview:songTitle];
}
//NSLog(#"\n\n temp: \n %#",temp);
cell.textLabel.text = [temp objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.font = [UIFont fontWithName:#"Gill Sans" size:20];
cell.textLabel.textColor = [UIColor colorWithRed:102.0/255 green:204.0/255 blue:170.0/255 alpha:1];
//cell.textLabel.textColor =[UIColor colorWithRed:(CGFloat)0.24 green:(CGFloat)0.7 blue:(CGFloat)0.45 alpha:(CGFloat)1];
cell.backgroundColor = [UIColor blackColor];
[[cell textLabel] setTextAlignment:UITextAlignmentLeft];
//cell.textLabel.adjustsFontSizeToFitWidth = YES;
//cell.detailTextLabel.numberOfLines = 2;
return cell;
}

Related

how to store objects of class file in an array in iphone

i am new in iphone app development.So please help me out. I am trying to develop an application in which i need to display contacts name number and image in a table view.I have a class file named Records.h and Records.m having three objects of NSString type name, number and image. i select data from the database and store each data in the objects of this class file like this :
Records *data = [[Records alloc] init];
data.contactname = [NSString stringWithUTF8String: (char *) sqlite3_column_text(stmt, 1)];
data.contactnumber = [NSString stringWithUTF8String: (char *) sqlite3_column_text(stmt, 2)];
data.contactimage = [NSString stringWithUTF8String: (char *) sqlite3_column_text(stmt, 3)];
And then i store this class file in NSMutableArray:
[array addObject:data];
such that at the every index i have each object with all the three strings name,number and image. Now i want to select only the name part from the every index. Any idea how to do it..??
In your tableview cellForRowAtIndexPath method write following code :
Records *shareObj = [array objectAtIndex:indexPath.row];
label.text=shareobj.name;
label2.text=shareobj.contactnumber;
Try this ::
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Records *objRecord = [array objectAtIndex:indexPath.row];
NSLog(#"Name :: %#", objRecord.name);
lbl.title.text = objRecord.name;
}
Thanks.
//in . h file
#property (strong, nonatomic) UILabel *labelContactName;
#property (strong, nonatomic) UILabel *labelContactNumber;
//in . m file
_labelContactName = [[UILabel alloc] initWithFrame:CGRectMake(50, 0, 230, 32)];
_lableContactName.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:_labelContactName];
_labelContactNumber= [[UILabel alloc] initWithFrame:CGRectMake(50, 27, 110, 20)];
_lableContactNumber.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:_labelContactNumber];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Records *objRecord = [array objectAtIndex:indexPath.row];
NSLog(#"Name :: %#", objRecord.name);
_lableContactName.text=objRecord.name;
}

UISwitch untoggling on scroll of a UITableView

I have a UITableView with a UISwitch as the accessoryView. My problem is that if I toggle one of the switches then scroll so the switch it out of view it returns to its previous state.
Please see video.
Does anyone know why this might be and how to solve it?
Here is the code that adds the switch view and deals with its action.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"POICell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier ];
//set the cell text to the
cell.textLabel.text = [self.catNames objectAtIndex:[indexPath row]];
NSString *toggle = [self.toggleArray objectAtIndex:[indexPath row]];
//add switch
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//create an instance of the database oject
DataBase * dataBase = [[DataBase alloc] init];
//open the database connection
[dataBase openDB];
NSString *imageName = [dataBase getPinImageNameFromCatID:[self.catIDs objectAtIndex:[indexPath row]]];
//get the root file path for the images
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/pinImages/%#",documentsDirectory, imageName];
//add image
NSURL *imageURL = [NSURL fileURLWithPath:filePath];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
cell.imageView.image = image;
NSLog(#"%#",[self.catIDs objectAtIndex:[indexPath row]]);
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchView;
[switchView addTarget:self action:#selector(switchChanged: ) forControlEvents:UIControlEventValueChanged];
if ([toggle isEqualToString: #"OFF"]) {
[switchView setOn:NO animated:NO];
}else{
[switchView setOn:YES animated:NO];
}
return cell;
}
- (void) switchChanged:(id)sender {
//get the switch that it was sent from
UISwitch *switchInCell = (UISwitch *)sender;
//get the cell it was sent from
UITableViewCell * cell = (UITableViewCell *) switchInCell.superview;
//get the row it was sent from
NSIndexPath * indexpath = [self.inputTableView indexPathForCell:cell];
//cast the indexpath to int
NSInteger variable = indexpath.row;
//set the filter as off in the user defualts.
[self.filterDic setValue:switchInCell.on ? #"ON" : #"OFF" forKey:[self.catIDs objectAtIndex:variable]];
//store the newdic in the user defualts
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
//save the dic to user defaults
[prefs setObject:self.filterDic forKey:#"pinFilters"];
}
Thanks for any help.
There are two issues with your code (at least :)
Let me start with the one that is confusing you.
You set the status of each witch based on toggle. And the value of toggle is tanken from an array self.toggleArray.
Fine so far.
But when a value changes and the action switchChanged is called then you update self.filterDic but you do not update self.toggleView.
And this causes the problem:
Next time when a cell becomes visible cellForRowAtIndexPath is called again and will set the value based on toggle wich is based on self.toggleArray. And that still has the old values in it ... you see?
You are making this mistake probably because you have not yet fully understood the cell recycle mechanism. And that is probably what causes the second issue that I identified. Let me try to explain.
iOS or cocoa respectively tries to allocate as view cell objects as nessessary. That means that a cell wich scrolls off the creen is added to a pool from which it can be re-used the next time when a (similar) sell is required. So each time when there is a need for a new cell (one that becomes visible) cellForRowAtIndexPath is called. Wihin that you fetch a cell using dequeueReusableCellWithIdentifier. If there is a cell in that pool that was initialized with the same re-use identfier then that one (or one of those) is returned to the caller.
In recent iOS (respectively SDK versions) versions a new cell will be allocated and returned if none of these cells exists. (And that is why Murali's suggestion would not work perfectly either)
In older versions you had to check cell for nil and alloc/init a new on in those cases.
After that you freely allocate new subview objects regardless whether the cell was re-cycled and already has those subviews or not. Then you add and add and add the same subviews again and again.
How can you solve this? There are, as usual, several ways of dealing with that:
First - Check whether the cell was re-used or not. Just check if the Switch is already there or not. For doing that you could tag it with some value different from 0 and fetch the subview with this tag. If you dont't get it then the cell is new and you have to create all the additional subvies.
Second - You could always erase all subviews from the cell right after fetching the cell with dequeueReusableCellWithIdentifier. That is the easiest solultion because you do not have to change mutch to your existing code. It is not the most performant solution though.
Third - The most elegant solution is probably to subclass UITableViewCell every time when you want to add custom elements to a cell. In that case its init method would be called only once upon creation (and not upon re-usage) and there you can programmatically add all the custom subviews. You can, of course, design the cell and add all subviews in IB as you can with every UIView object. Witin cellForRowAtIndexPath you would only have to care for setting the appropriate values.
Perhaps your cells are being recycled.
Have a look at the accepted answer here:
iphone : uitableview : contents of a cell change on scrolling
Please use this method..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"POICell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UISwitch *switchView;
if (cell == nil)
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier ];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
switchView = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];//Change the frame
cell.accessoryView = switchView;
}
//set the cell text to the
cell.textLabel.text = [self.catNames objectAtIndex:[indexPath row]];
NSString *toggle = [self.toggleArray objectAtIndex:[indexPath row]];
//add switch
//create an instance of the database oject
DataBase * dataBase = [[DataBase alloc] init];
//open the database connection
[dataBase openDB];
NSString *imageName = [dataBase getPinImageNameFromCatID:[self.catIDs objectAtIndex:[indexPath row]]];
//get the root file path for the images
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/pinImages/%#",documentsDirectory, imageName];
//add image
NSURL *imageURL = [NSURL fileURLWithPath:filePath];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
cell.imageView.image = image;
NSLog(#"%#",[self.catIDs objectAtIndex:[indexPath row]]);
[switchView addTarget:self action:#selector(switchChanged: ) forControlEvents:UIControlEventValueChanged];
if ([toggle isEqualToString: #"OFF"]) {
[switchView setOn:NO animated:NO];
}else{
[switchView setOn:YES animated:NO];
}
return cell;
}

Searching issue-iphone sdk

I have a tableview that contains cell images and names as text. At the top i have added a searchbar. And when I search i am able to do the search for names, but the images are still the same. How can change the images also, as per the changes in names when search?
this code in the tableview delegate, and i'm using some search delegate methods also. I haven't done anything to arrange the images with respect to the names. I need help to implement that.
if(searching)
cell.textLabel.text = [copyListOfItems objectAtIndex:indexPath.row];
else {
[cell.imageView setImageWithURL:[NSURL URLWithString:[imageArray objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:#"defaultPerson.png"]];
cell.textLabel.text = [friendsList objectAtIndex:indexPath.row];
}
Here is few more code:
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSString *sTemp in friendsList)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
Thanks.
It seems to me that you are not updating your cells correctly.
A simple [myTableView reloadData]; might help, but you might also want to consider looking into the way you are adding the imageViews to you cells. You might not have removed(/released/nilled) the imageViews you place on top of your cells correctly. You have to do this everytime you update your cells as well since the imageViews won't do this themselves unless you specifically told them so.
When you updated your question with some helpful code I can be more specific about this concerning your problem.
Now that you did edit your post with some (although very little amount of) code I can see from this snippet that you are not updating your cell.imageViews to the new list of objects.
You updated your uitableview with the new "copyListOfItems" but you didn't do that same thing for your images resulting in the display of the old content which are the images from "imageArray"
You need to make a similar array for your images as you did with the text.
if(searching)
{
cell.textLabel.text = [copyListOfItems objectAtIndex:indexPath.row];
[cell.imageView setImageWithURL:[NSURL URLWithString:[searchedArrayOfImages objectAtIndex:indexPath.row]];
}
else {
[cell.imageView setImageWithURL:[NSURL URLWithString:[imageArray objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:#"defaultPerson.png"]];
cell.textLabel.text = [friendsList objectAtIndex:indexPath.row];
}
A better way (i.m.o.) to save images to names is making a NSDictionary for them so when you pick a record your name always fits your image.
In regards of the comments below:
At the moment you search, mostlikely in the textDidChange delegate method, you mostlikely pick the indexrows of all your search matches. At the moment you pick the index of a hit from "friendlist" and put it into "copyListOfItems" you also need to use the very same index and take the image from "imageArray" and put them into "searchedArrayOfImages". This way you build both your text- and image array the same way. Then when you reload your tableview you can take the same index from "copyListOfItems" and from "searchedArrayOfImages" and populate your cell properly.
It would look something like this:
- (void) searchTableView
{
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
int indexCount = 0; //keeps track of which index you are at.
for (NSString *sTemp in friendsList)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
{
[copyListOfItems addObject:sTemp]; //this is your name result
[searchedArrayOfImages addObject:[imageArray objectAtIndex:indexCount]]; //adds image that fits with the nameresult to array of searched images
}
indexCount++;
}
[searchArray release];
searchArray = nil;
}
When you are done searching the cells will be updated like this (according to your snippet)
if(searching)
{
cell.textLabel.text = [copyListOfItems objectAtIndex:indexPath.row];
[cell.imageView setImageWithURL:[NSURL URLWithString:[searchedArrayOfImages objectAtIndex:indexPath.row]];
}
else
{
[cell.imageView setImageWithURL:[NSURL URLWithString:[imageArray objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:#"defaultPerson.png"]];
cell.textLabel.text = [friendsList objectAtIndex:indexPath.row];
}
This should suffice^^ good luck.

TTT attributed Label Multi- colored Font help

-(UITableViewCell*) makeLikeCell
{
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"SpotlightLikesTableViewCell" owner: self options: nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
UITableViewCell *cell = [topLevelObjects objectAtIndex:0];
NSString *likeText = [likesAndComments objectAtIndex: kLikeRow];
TTTAttributedLabel *likeLabel = [[[TTTAttributedLabel alloc] initWithFrame:CGRectZero] autorelease];
likeLabel = (TTTAttributedLabel*) [cell viewWithTag: kCaptionTag];
likeLabel.textColor = [UIColor blueColor];
likeLabel.lineBreakMode = UILineBreakModeWordWrap;
[likeLabel setFont: [UIFont fontWithName: #"Helvetica Neue" size: 10]];
[likeLabel setText: likeText afterInheritingLabelAttributesAndConfiguringWithBlock: ^NSAttributedString *(NSMutableAttributedString *mutableAttributedString) {
NSRange colorRange = [[mutableAttributedString string] rangeOfString: #" like this photo." options: NSCaseInsensitiveSearch];
[mutableAttributedString addAttribute:(NSString *) kCTForegroundColorAttributeName value:(id)[[UIColor grayColor] CGColor] range:colorRange];
return mutableAttributedString; }];
return cell;
}
I added the TTT attributed label to my project. I want to have 2 different font colors to display the "likes". However my project keeps crashing. A sample string to be formatted would be: "andrew, john, amos likes this photo."
any suggestions?
Use like this
[likeLabel setText:likeText afterInheritingLabelAttributesAndConfiguringWithBlock: ^(NSMutableAttributedString *mutableAttributedString) {
NSRange colorRange = [likeText rangeOfString: #"like this photo." options: NSCaseInsensitiveSearch];
if (colorRange.location != NSNotFound) {
[mutableAttributedString addAttribute:(NSString *) kCTForegroundColorAttributeName value:(id)[[UIColor grayColor] CGColor] range:colorRange];
}
return mutableAttributedString;
}];
There is a way to set different / multiple fonts & other properties like color on Label using NSMutableAttributedStrin. Refer to my answer on Multiple Font & Color for string & Display the string on Label

iphone detailtext in UITableView question

So, I am able to create an array that populates the fields of the Table, but am having troubles creating the subtext that appears below the main fields. I currently have:
- (void)viewDidLoad {
[super viewDidLoad];
listOfForms = [[NSMutableArray alloc] init];
[listOfForms addObject:#"First Form"];
}
and then:
NSString *cellValue = [listOfDAForms objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
in the cellForRowAtIndexPath portion. Why can't I add:
listOfNames = [[NSMutableArray alloc] init];
[listOfNames addObject:#"Named Form"];
and
NSString *cellSubscript = [listOfNames objectAtIndex:indexPath.row];
cell.detailTextLabel.text = cellSubscript;
in order to make the little subview work? What am I doing wrong?
Be sure to init your cell with the style UITableViewCellStyleSubtitle