I've got a tableView populated with twitter accounts that I want to write to a .plist when a user selects one. Currently, however, when I tap an account, it writes the textLabel.text of the bottom cell.
Here's my code.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:#"test.plist"];
NSMutableArray *testArray = [[NSMutableArray alloc] init];
[testArray addObject:cell.textLabel.text];
NSArray *context = [[NSMutableArray alloc] initWithObjects:#"Name", nil];
NSMutableDictionary *new = [[NSMutableDictionary alloc] initWithObjects:testArray forKeys:context];
[new writeToFile:writablePath atomically:YES];
}
I don't see where the cell object is being created at. If you want to get the cell that was just selected, you can do this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
}
This will allow you to grab the actual cell that the user 'touched'.
Related
I create a UITableView programmatically with different cells and sections that connects to the other views in storyboard
But if you check the story board absence view has custom cell with check box sections that it's not appear here
My question is:
why it doesn't shows the custom cell?,would you please helping me
Thanks in advance!
Here is my code:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString: #"WorkTime"]){
[segue.destinationViewController setTitle:#"WorkTime"];
}if([segue.identifier isEqualToString: #"Absence"]){
[segue.destinationViewController setTitle:#"Absence"];
}if([segue.identifier isEqualToString: #"Compensation"]){
[segue.destinationViewController setTitle:#"Compensation"];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *keys = [[NSMutableArray alloc] init];
NSMutableDictionary *contents = [[NSMutableDictionary alloc] init];
NSString *workKey = #"work";
NSString *absKey = #"absence";
NSString *comKey = #"compensation";
[contents setObject:[NSArray arrayWithObjects:#"Work Time", nil] forKey:workKey];
[contents setObject:[NSArray arrayWithObjects:#"Absence", nil] forKey:absKey];
[contents setObject:[NSArray arrayWithObjects:#"Compensation", nil] forKey:comKey];
[keys addObject:workKey];
[keys addObject:absKey];
[keys addObject:comKey];
[self setSectionKeys:keys];
[self setSectionContents:contents];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
[[cell textLabel] setText:contentForThisRow];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_selectedIndex = indexPath.row;
[self.tableView reloadData];
//case1
[self performSegueWithIdentifier:#"WorkTime" sender:self];
//case2
[self performSegueWithIdentifier:#"Absence" sender:self];
//case3
[self performSegueWithIdentifier:#"Compensation" sender:self];
}
I think your problem is here
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Your custom cell should have a unique cell identifier. You need to pass that unique cell identifier to -dequeueReusableCellWithIdentifier:.
What have you used as your cell identifier?
you should use NSLOG to be sure that you are going to different views, I think you are always in a same view is the reason that you cann't see the new changes
I create a table view controller programmatically that contains different sections I want to add 3 rows with check mark box in my third sections (I used storyboard!)
would you please give me some hint that how can I do that ..
my question is how can I set checkbox in left side for my third sections
here is the picture:instead of Please set your code: having 3 rows with check mark box in Absence Code sections
Here is my view in storyboard:
Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *keys = [[NSMutableArray alloc] init];
NSMutableDictionary *contents = [[NSMutableDictionary alloc] init];
NSString *staKey = #"Start";
NSString *endKey = #"End";
NSString *absKey= #"Absence";
[contents setObject:[NSArray arrayWithObjects:#"Time: 08:00 Date: Fri,3 Aug, 2012", nil] forKey:staKey];
[contents setObject:[NSArray arrayWithObjects:#"Time: 17:57 Date: Fri,3 Aug, 2012", nil] forKey:endKey];
[contents setObject:[NSArray arrayWithObjects:#"Please set your code", nil] forKey:absKey];
[keys addObject:staKey];
[keys addObject:endKey];
[keys addObject:absKey];
[self setSectionKeys:keys];
[self setSectionContents:contents];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
[[cell textLabel] setText:contentForThisRow];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSMutableArray *weekArray = [[ NSMutableArray alloc] initWithObjects: #"Start Time", #"End Time",#"Absence Code",
nil];
return [weekArray objectAtIndex:section];
}
- (UITableViewCellAccessoryType)tableView:(UITableView *)tv accessoryTypeForRowWithIndexPath:(NSIndexPath
*)indexPath {
return UITableViewCellAccessoryDisclosureIndicator;
}
Thanks in advance!
Each checkbox cell should be a Custom TableViewCell. Then simply drop an ImageView and a Label in the TableViewCell and use didSelectRowAtIndex: to toggle the image between checked/unchecked.
EDIT:
Check Selecting multiple rows of a UITableView link get helped.
Do this: change code in below method:
- (UITableViewCellAccessoryType)tableView:(UITableView *)tv accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
if(indexPath.section ==2)
{
return UITableViewCellAccessoryCheckMark;
}
else
{
return UITableViewCellAccessoryDisclosureIndicator;
}
}
I'm making an iOS that lists the files in the Documents dictionary. I want to display this data in a UITableView, the problem is that it's not working.
It loads the data in to the view. Then the application freezes and calls EXC_BAD_ACCESSThis is my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
timesRun = 0;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectoryPath error:nil];
[bundleRoot release];
NSLog(#"Count: %i",[dirContents count]);
return [dirContents count];
}
- (UITableViewCell *)tableView:(UITableView *)tableViewData cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil;
int Locatation = indexPath.row;
Locatation++;
cell = [tableViewData dequeueReusableCellWithIdentifier:#"MyCells"];
if (cell == nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"]autorelease];
}
//cell.textLabel.text = [NSString stringWithFormat:#"Cell: %i",Locatation];
cell.textLabel.text = [dirContents objectAtIndex:timesRun];
timesRun++;
return cell;
NSLog(#"Did return");
}
- (void)tableView:(UITableView *)tableViewDat didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"%#",cell.textLabel.text);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
This displays a basic misunderstanding of the concept of the table view data source.
My suggestion:
Create an array that contains the files outside any tableview methods. Then you use that array to feed the tableview.
Use array.count to return numberofrowsatindexpath.
Also, on providing the cells at cellforrowatindexpath, don't use iterations/counters. The tableview ask for each element of your array itself using the indexpath argument. You access it like this:
id object = [array objectArIndex: indexPath.row]
And you then use the objects attributes to set the labels of the cell.
Please read a tutorial on tableviews. I recommend itunesU Paul hegarty's lectures. They're really great.
Ps. You release the bundleRoot object in numberofrowsinsection, which you don't retain (or use at all) which is most likely causing your crash.
Edit:
With a little more spare time, I retouched your code:
//code not tested/written in xcode. Might contain typos
//in your .m file
//in your (private) interface
#property (nonatomic, retain, readonly) NSArray *dirContents;
//in your implementation
#synthesize dirContents=_dirContents;
-(NSArray*) dirContents {
if (!dirContents) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
_dirContents = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectoryPath error:nil] retain];
}
return _dirContents;
//note that if you want to "refresh" the contents you would have to
//release _dirContents and set it to nil or implement this differently
}
-(void) dealloc {
[_dirContents release];
//....
[super dealloc];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [[self dirContents] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"MyCells"];
if (cell == nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCells"]autorelease];
}
cell.textLabel.text = [[self dirContents] objectAtIndex: indexPath.row];
return cell;
// NSLog(#"Did return"); //this never gets called by the way
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"%#",cell.textLabel.text);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
My problem was sort of like Mario's answer. [dirContents count] returned a higher value than the amount of times it could add an object from the array.In other words it was a Out of Bounds error.
Make sure you are not releasing dirContents while using that.I am sure you are not doing but just cross check with your code.
Hi I am new to iOS programming and I need a little help.
I have a table view cell which is populated by data from a .plist file. I need to be able to make a link within one of the cells. How could I do this?
Here is the code which is loading the data into the cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CustomTableCell";
static NSString *CellNib = #"DetailViewCell";
DetailViewCell *cell = (DetailViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (DetailViewCell *)[nib objectAtIndex:0];
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.cellTitleLabel.textColor = [UIColor blackColor];
cell.cellTitleLabel.font = [UIFont systemFontOfSize:20.0];
cell.cellSubtitleLabel.textColor = [UIColor darkGrayColor];
informations = [[NSArray alloc] initWithObjects:#"City", #"Country", #"State", #"History", #"Link", nil];
subtitles = [[NSArray alloc] initWithObjects:titleString, subtitleString, stateString, populationString, #"Link", nil];
cell.cellTitleLabel.text = [informations objectAtIndex:indexPath.row];
cell.cellSubtitleLabel.text = [subtitles objectAtIndex:indexPath.row];
return (DetailViewCell *) cell;
}
For the cell "Link" I need it to open a url which is stored in the .plist file. How could i do this?
Many thanks
Ryan
PS: I'm a newbie at this stuff, so be descriptive. Thanks
Firs of all, move the following to viewDidLoad
informations = [[NSArray alloc] initWithObjects:#"City", #"Country", #"State", #"History", #"Link", nil];
subtitles = [[NSArray alloc] initWithObjects:titleString, subtitleString, stateString, populationString, #"Link", nil];
Second, for the cell that has a value of #"Link"
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.cellTitleLabel.text == #"Link")
{
//Open in safari
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:cell.cellSubtitleLabel.text]];
}
}
Make the two arrays properties of your viewController.
#property (nonatomic, retain) NSArray *informationArray, *subtitlesArray;
Initialise them in your -viewDidLoad method:
self.informationArray = [NSArray arrayWithObjects:#"City", #"Country", #"State", #"History", #"Link", nil];
self.subtitlesArray = [NSArray arrayWithObjects:titleString, subtitleString, stateString, populationString, #"Link", nil];
and then check to see if the retrieved data is a link, then open it in safari.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
id title = [self.informationArray objectAtIndex:indexPath.row];
NSURL *link = [NSURL URLWithString:[self.subtitlesArray objectAtIndex:indexPath.row]];
//or to get the link out of a .plist
NSDictionary *plist = [NSData dataWithContentsOfFile:filePathForPlist];
NSURL *link = [NSURL URLWithString:[[plist objectForKey:title] objectForKey:#"Link"];
// you may need to get a different object from the .plist depending on the structure of the file.
//Check to see if the indexPath matches a cell with a title of "Link" and that the URL can be opened.
if([title isEqualToString:#"Link"] && [[UIApplication sharedApplication] canOpenURL:link]) {
[[UIApplication sharedApplication] openURL:link];
}
}
I am working for the first time in objective c and have come across an issue that I have not seen an answer for.
I am loading a set of data from a JSON data set and using it to populate a UITableView within a UITableViewController.
First when the view is loaded (viewDidLoad) I populate the array with the JSON data from a URL.
Next the data loads as it should. numberOfRowsInSection shows that there are 30 results in the array which is correct.
However The Iphone loads the entire set three times into the tableview.
Here is some code from the controller for that view:(Twitter is being used as an example and is not the actual data set I use)
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
//results = [[NSMutableArray alloc] init];
self.navigationItem.title=#"public_timeline";
self.tableView.allowsSelection = NO;
NSString *url = [[NSString alloc] init];
url = [[NSString alloc] initWithFormat:#"http://twitter.com/statuses/%s.json",#"public_timeline"];
if ([results count] == 0) {
[self parseJSON:url];
}
}
Here is the parseJSON (actual parse is done with the Cocoa JSON framework
-(void) parseJSON:(NSString *)URL{
NSURL *JSONURL = [NSURL URLWithString:URL];
NSData *responseData = [[NSData alloc] initWithContentsOfURL:JSONURL];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
results = [[NSMutableArray alloc] initWithArray:[responseString JSONValue]];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [results count];
}
then the cell's output
- (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] autorelease];
// Set up the cell...
}
NSDictionary *cdict = [results objectAtIndex:indexPath.row];
cell.textLabel.text = [cdict valueForKey:#"text"];
return cell;
}
I am not sure if what I am doing is the best way to do this, so if someone could help me out that would be great.
Check the numberOfSectionsInTableView Method and change the return Value to 1
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}