using UIDatePicker on static cell - objective-c

I want to display the date picked from UIDatePicker on the static cell.
The problem code is below. I want to change self.label.text by changing the date with UIDatePicker, but it doesn't change.
- (IBAction)inputDate:(id)sender {
self.label.text = [NSString stringWithFormat:#"%#", self.datePicker.date];
}
Method inputDate: is wired to UIDatePicker.
Property datePicker is also wired to UIDatePicker.
Is there any specific way to change static cells? Thanks for your kindness.

I would recommend you store the cell that you want to change as an ivar in your table view:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//...
// configure your birth date cell
self.birthDateCell = cell;
//...
}
Then your method would look something like:
- (IBAction)inputDate:(id)sender {
self.birthDateCell.label.text = [NSString stringWithFormat:#"%#", sender.date];
}
And that should do it. Additionally, make sure you are calling the inputDate function with the appropriate event action for the date picker.
EDIT: Additionally, you may need to reload your cell to present the data like so:
- (IBAction)inputDate:(id)sender {
self.label.text = [NSString stringWithFormat:#"%#", sender.date];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:NO];
}

Just one row code solved the Problem. Stunner's advice is very helpful for this final answer.
- (IBAction)inputDate:(id)sender {
self.label.text = [NSString stringWithFormat:#"%#", self.datePicker.date];
[self.tableView reloadData]; // <- add this row !
}

Related

wait for request and then tableview call

I am using a ASIHTTPRequest to get a value from the url. this process is done in view did load. and I get value from a url store in an array. I have one table view. The problem is when I run the app table view is first called and it take array value is 0. my request is taking some time for loading. how to solve it.i am new to us. help me. i want to lode that array in to my tableview.
May I know what is the correct way to achieve my objective?
NSString *s= [NSString stringWithFormat:#"http:///blog/api/get_category_posts/?id=%#",value];
s=[s stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url1=[NSURL URLWithString:s];
ASIHTTPRequest *req2=[[ASIHTTPRequest alloc]initWithURL:url1];
[req2 setDelegate:self];
[req2 startAsynchronous];}-(void)requestFinished:(ASIHTTPRequest *)request
{
tableResourceArray=[request.responseString JSONValue];
NSLog(#"TempArray:%d",tableResourceArray.count);} -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return tableResourceArray.count;
}
just reload table after get response.
in your case
[req2 startAsynchronous];}
-(void)requestFinished:(ASIHTTPRequest *)request
{
tableResourceArray=[request.responseString JSONValue];
[tableName reloadData]; // ** that's you need**
NSLog(#"TempArray:%d",tableResourceArray.count);
}
-(NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return tableResourceArray.count;
}

Passing data between view controllers in storyboards using segue

I'm new at iOS development and after reading many tutorials about passing variables and i still need your help.
This function in my PP.m file:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Btn1Transport"])
{
[segue.destinationViewController setMyData:(50)];
NSLog(#"Transporter1");
}
if ([segue.identifier isEqualToString:#"Btn2Transport"])
{
[segue.destinationViewController setMyData:(100)];
NSLog(#"Transporter2");
}
}
This is in my Category.m file:
- (void)viewDidLoad{
[super viewDidLoad];
recipeLabel.text = #"Hello"; //for test, is working
}
-(void)setMyData:(int)myData
{
NSLog(#"Happines %d",myData);
NSString* result = [NSString stringWithFormat:#"%d", myData];
recipeLabel.text = result; //not working
}
The problem is at the line NSLog(#"Happines %d",myData); my data prints just fine, but not gets set to recipeLabel. So for testing if it works i made recipeLabel.text = #"Hello"; and the label is just fine. What am I doing wrong? And sorry for the beginner question.
No, you can't write to the TextLabel directly from the prepareForSegue event, the value will be overwritten when the destination view controller will load ...
You have to set a variable in the destination view controller and then you have to set the value of your label equal to the value of the variable in the viewDidLoad event of the destination view controller to make it works ...
//The variable myIntVar is a private variable that should be declared in the header file as private
- (void)viewDidLoad{
[super viewDidLoad];
recipeLabel.text = myIntVar; //set the value equal to the variable defined in the prepareForSeque
}
-(void)setMyData:(int)myData
{
NSLog(#"Happines %d",myData);
NSString* result = [NSString stringWithFormat:#"%d", myData];
myIntVar = result;
}

Delay when refreshing UITableView custom cell

I have a UITableView with a custom cell which i fill (with array infoservices) after parsing the xml data.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
ApplicationCell *cell = (ApplicationCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[self.cellNib instantiateWithOwner:self options:nil];
cell = tmpCell;
self.tmpCell = nil;
}
infoService *e = [self.infoservices objectAtIndex:indexPath.row];
cell.name = [e infoName];
NSString *infodetails = [e infoDetails];
if ( infodetails == nil ) {
cell.details = #"Loading...";
[self startInfoDownload:e forIndexPath:indexPath];
NSLog(#"Loading...");
} else {
cell.details = infodetails;
NSLog(#"Show info detail: %#", infodetails );
}
return cell;
}
- (void)infoDidFinishLoading:(NSIndexPath *)indexPath
{
infoDownloader *infoserv = [imageDownloadsInProgress objectForKey:indexPath];
if (infoserv != nil)
{
[infoservices replaceObjectAtIndex:[indexPath row] withObject:infoserv.appRecord];
NSIndexPath *a = [NSIndexPath indexPathForRow:indexPath.row inSection:0]; // I wanted to update this cell specifically
ApplicationCell *cell = (ApplicationCell *)[self.tableView cellForRowAtIndexPath:a];
cell.details = [[infoservices objectAtIndex:[indexPath row]] infoDetails];
NSLog(#"Updating=%#", [[infoservices objectAtIndex:[indexPath row]] infoDetails]);
}
}
For each cell i'm using NSURLConnection sendAsynchronousRequest to retrieve and parse xml data from object infoDownloader with
- (void)startDownload
for each individual cell.
After data has been successfully parsed delegate method from infoDownloader is called
- (void)infoDidFinishLoading:(NSIndexPath *)indexPath
The problem is that, while the
- (void)infoDidFinishLoading:(NSIndexPath *)indexPath
gets called after parsing each cell and i can see the
NSLog(#"Updating=%#", [[infoservices objectAtIndex:[indexPath row]] infoDetails]);
in the debugger with the correct details, the cell does not get refreshed immediately but after 6 or 7 seconds. Also cellForRowAtIndexPath does not get called from
- (void)infoDidFinishLoading:(NSIndexPath *)indexPath
for some reason because there is not debug output after the infoDidFinishLoading. Also i don't understand how the cell.details gets actually refreshed since cellForRowAtIndexPath isn't called again.
I've tried to setup this function using Apple's LazyTableImages loading example, which i have used successful, but i don't know what's going wrong.
You may need to call reloadRowsAtIndexPaths once the data has been loaded. What could be happening is that the cell data has been loaded but the cell drawing is not updated.
Also I believe your code can request the same data multiple times because if [e infoDetails] is nil a request is made, but the cell could be requested multiple times before the data is loaded so [self startInfoDownload:e forIndexPath:indexPath] would be called multiple times, downloading the same data. You should look into keeping track of which rows you have requested data for.
Check out this code for some ideas on how to solve this: https://github.com/kgn/Spectttator/blob/master/SpectttatorTest-iOS/RootViewController.m#L123
Any changes affecting UI must be performed on main thread.
Refreshing tableView, by changing cells details, realoading tabe view, realoding rows... are changes affecting UI.
In particular, you should perform your changes in the main thread using :
dispatch_async(dispatch_get_main_queue(), ^{
cell.details = [[infoservices objectAtIndex:[indexPath row]] infoDetails];
}
or prior to iOS 4 :
cell performSelectorOnMainThread:#selector(setDetails:) withObject:[[infoservices objectAtIndex:[indexPath row]] infoDetails];

How Can I Pass Data from Array in didLoadObjects to cellForRowAtIndexPath

So, I'm using RestKit to access a webservice and retrive data from there.
So far I have two views, and that part of retrieving the data is fine, and I get the 100 objects I need, saving them into an array called "songs".
Here is didLoadObjects:
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
NSLog(#" Reached didLoadObjects: %d", [objects count]);
self.songs = objects;
NSLog(#"%#",self.songs);
}
Ok, I have two views, and the problem is, of course, on the second one. I'm using Storyboards. I gave the tableView cell an identifier called "TopListCellIdentifier".
So, I get the objects, all the 100 of them are "printed" in the command line, but the problem starts when I try to access the data from the array inside cellForRowAtIndexPath, something which has to be done because I have a custom tableViewCell displaying the info I need (sons, artists, covers, stuff like that). So, when I start the app, the first view is fine, but the second has 100 cells, but no info. Here is the cellForRowAtIndexPath code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *TopListCellIdentifier = #"TopListCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TopListCellIdentifier];
// Loading the Cover Images in the Background
// Cover Image: Tag 1
[((HJManagedImageV*)[cell viewWithTag:1]) clear];
HJManagedImageV* thumbImage = ((HJManagedImageV*)[cell viewWithTag:1]);
NSString *thumbUrl = [[self.songs objectAtIndex:[indexPath row]] thumbnail];
thumbImage.url = [NSURL URLWithString:thumbUrl];
[[ImageHandler sharedHandler].imgManager manage:thumbImage];
//Song and Artist: Tag 2 and 3
((UILabel*)[cell viewWithTag:2]).text = [[self.songs objectAtIndex:[indexPath row]] title];
((UILabel*)[cell viewWithTag:3]).text = [[self.songs objectAtIndex:[indexPath row]] artist];
//Arrow Up/Down/Same: Tag 4
//TODO
//Position Number: Tag 5
((UILabel*)[cell viewWithTag:5]).text = [NSString stringWithFormat:#"%d.", [indexPath row]+1];
return cell;
}
I've tried to put a debugger in the first line of cellRow(...) but the program doesn't enter there. I feel like i'm forgetting about something very simple, but I can't seem to figure out what.
Can someone help me, please?
You're never initing a new cell. You need to add a line like :
if (nil == cell)
cell = [[UITalbeViewCell alloc] init...
after your call to
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TopListCellIdentifier];

Trouble with Asynchronous Downloading UITableView

I am trying to asynchronously download images for a UITableViewCell, but it is currently setting the same image to each cell.
Please can you tell me the problem with my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
SearchObject *so = (SearchObject *)[_tableData objectAtIndex:indexPath.row];
cell.textLabel.text = [[[[so tweet] stringByReplacingOccurrencesOfString:#""" withString:#"\""] stringByReplacingOccurrencesOfString:#"<" withString:#"<"] stringByReplacingOccurrencesOfString:#">" withString:#">"];
cell.detailTextLabel.text = [so fromUser];
if (cell.imageView.image == nil) {
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:[so userProfileImageURL]]];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
[conn start];
}
if ([_cellImages count] > indexPath.row) {
cell.imageView.image = [UIImage imageWithData:[_cellImages objectAtIndex:indexPath.row]];
}
return cell;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_cellData appendData:data];
[_cellImages addObject:_cellData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self.tableView reloadData];
}
You are appending the data from every image downloaded to the same data object. So in the best case the data object ends up with the data for image #1 immediately followed by the data for image #2 and so on; the image decoder is apparently taking the first image in the chunk of data and ignoring the garbage after. You also seem to be unaware that NSURLConnections' connection:didReceiveData: will not necessarily be called in the order that the connections were started, that connection:didReceiveData: can be called zero or multiple times per connection (and probably will if your images are more than a few kibibytes), and that tableView:cellForRowAtIndexPath: is not guaranteed to be called for every cell in the table in order. All of which are going to totally screw up your _cellImages array.
To do this right, you need to have a separate NSMutableData instance for each connection, and you need to add it to your _cellImages array just once, and at the correct index for the row rather than at the arbitrary next available index. And then in connection:didReceiveData: you need to figure out the correct NSMutableData instance to append to; this could be done by using the connection object (wrapped in an NSValue using valueWithNonretainedObject:) as the key in an NSMutableDictionary, or using objc_setAssociatedObject to attach the data object to the connection object, or by making yourself a class that handles all the management of the NSURLConnection for you and hands you the data object when complete.
I don't know if this is causing the problem or not, but in your connection:didReceiveData: method you're just appending the image data to the array; you should be storing the image data in such a way that you can link it to the cell it's supposed to be shown in. One way to do this would be use an NSMutableArray populated with a bunch of [NSNull]s, then replace the null value at the appropriate index when the connection has finished loading.
Also, you're appending the _cellData to the _cellImages array when the connection hasn't finished loading, you should only be doing this in the connection:didFinishLoading method.