I'm currently using a UITextView in a UITableViewCell in order to make links clickable, but this is giving very poor performance.
So I was wondering if it's possible to detect links in a NSString and if there is a link, use the UITextView, otherwise just use a UILabel.
Absolutely. Use NSDataDetector (NSDataDetector Class Reference)
I guess you are familiar with regexes to detect URLs, so in order to get one or the other type of view in your cell, you can simply return two different UITableViewCells from your tableView:cellForRowAtIndexPath: method.
It could look like this (please notice, typed in the browser not tested):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *dataString = // Get your string from the data model
// Simple pattern found here: http://regexlib.com/Search.aspx?k=URL
NSString *URLpattern = #"^http\\://[a-zA-Z0-9\-\.]+\\.[a-zA-Z]{2,3}(/\\S*)?$";
NSError *error = NULL;
NSRegularExpression *URLregex = [NSRegularExpression regularExpressionWithPattern:URLpattern
options:NSRegularExpressionCaseInsensitive
error: &error];
NSUInteger numberOfMatches = [URLregex numberOfMatchesInString:string
options:0
range:NSMakeRange(0, [string length])];
if ( numberOfMatches == 0 ) {
static NSString *PlainCellIdentifier = #"PlainCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
cell.textLabel.text = timeZoneWrapper.localeName;
}
else {
static NSString *FancyCellIdentifier = #"FancyCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
// Configure cell view with text view here
}
return cell;
}
Using this snip of code you would be able to find and get http url in UILable using NSDataDetector:
NSDataDetector* detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray* matches = [detector matchesInString:yourString options:0 range:NSMakeRange(0, [yourString. length])];
NSLog(#"%#",matches) ;
NSMutableAttributedString *MylabelAttributes =
[[NSMutableAttributedString alloc] initWithString:yourString];
for (int index = 0 ; index < matches.count; index ++) {
NSTextCheckingResult *textResult = [matches objectAtIndex : index];
NSTextCheckingType textResultType = textResult.resultType;
NSRange testRange = textResult.range;
NSURL *testUrl = textResult.URL ;}
After applying this code, you will be able to attribute your `UILabel` text:
[MylabelAttributes addAttribute:NSLinkAttributeName value:testUrl range: testRange];
[MylabelAttributes addAttribute:NSFontAttributeName
value:[UIFont boldSystemFontOfSize:7.0]range:NSMakeRange(0,yourString.length)];
Related
I've been trying to parse an array and split it into separate strings. I have managed to successfully get this working by individually adding a fixed objectAtIndex when I set the strings.
Example:
NSString *weightString = [[[results valueForKey:#"Endurance"] objectAtIndex:7]objectAtIndex:2];
However, when I try and set the strings in a tableView didSelectRowAtIndexPath using any objectAtIndex the string always returns null. I need to be able to click on the tableView row using objectAtIndex:indexPath.row. I can't work out where I am going wrong. Feel free to request more code or queries.
Query:
PFQuery *arrayQuery = [PFQuery queryWithClassName:#"Exercises"];
[arrayQuery selectKeys:#[#"Endurance"]];
[arrayQuery orderByAscending:#"ExerciseName"];
[arrayQuery findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
if (!error) { self.arrayResults = [results valueForKey:#"Endurance"];
cellForRowAtIndexPath:
- (TableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"list";
TableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *cellTitle;
cell.cellTitle.text = [[browseAllArray objectAtIndex: indexPath.row] objectForKey:#"ExerciseName"];
if (cell == nil) {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//Exercise Bar Label
cellTitle = [[UILabel alloc] initWithFrame:CGRectMake(80, 20, 220, 60)];
cellTitle.font = [UIFont fontWithName:#"ethnocentric" size:14];
cellTitle.textColor = [UIColor blackColor];
cellTitle.numberOfLines = 2;
cellTitle.textAlignment = NSTextAlignmentCenter;
cell.cellTitle.text = [[browseAllArray objectAtIndex: indexPath.row] objectForKey:#"ExerciseName"];
[self.tableView reloadData];
}
cellTitle.text = [[browseAllArray objectAtIndex:indexPath.row]objectForKey:#"ExerciseName"];
return cell;
I have managed to solve my problem by changing the string in the didSelectRowAtIndexPath method.
Instead of using:
NSString *weightString = [[[results valueForKey:#"Endurance"] objectAtIndex:indexPath.row]objectAtIndex:2];
I used:
NSString *weightString = [[arrayResults objectAtIndex:indexPath.row] objectAtIndex:2];
I decided to try and use the array instead of results string as it wouldn't let me pull the information from the string. I would recommend following #Larme 's steps above as they definitely sent me in the right direction.
If people are trying to follow my steps make sure you remove the valueForKey as this was throwing a fatal error.
In my tableview cell, there is a label for Description. The description text will be highlighted through Attributed Text in separate method. this method is call from cellforRowIndexPath & that's why tableview scroll is lagging a lot.
My code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
SearchVCCell *cell = (SearchVCCell *)[tableView dequeueReusableCellWithIdentifier:cellidentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SearchVCCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.lbl_title.text=[NSString stringWithFormat:#"%#",[arrTitle objectAtIndex:indexPath.row]];
cell.lbl_disc.text=[NSString stringWithFormat:#"%#",[arrDescription objectAtIndex:indexPath.row]];
cell.lbl_page.text=[NSString stringWithFormat:#"Page: %d",[[arrPageNumber objectAtIndex:indexPath.row]intValue]];
int p= [self highlightText:_search_bar.text :cell.lbl_disc]; //Method Call
cell.lbl_count.text=[NSString stringWithFormat:#"%d",p];
}
return cell;
}
HightText Method:
-(int) highlightText :(NSString *)srcTxt :(UILabel*)txtView {
int srcTxtLen = srcTxt.length;
int idx = 0,count=0;
while (idx<(txtView.text.length-srcTxtLen)) {
NSRange srcRange = NSMakeRange(idx, srcTxtLen);
if ([[txtView.text substringWithRange:srcRange] isEqualToString:srcTxt]) {
NSMutableAttributedString *tmpAttrTxt = [[NSMutableAttributedString alloc] initWithAttributedString:txtView.attributedText];
[tmpAttrTxt addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:srcRange];
txtView.attributedText = tmpAttrTxt;
idx += srcTxtLen;
count++;
} else {
idx++;
}
}
return count;
}
Help me to solve, Thanks in advance
you can replace your method call with this
NSMutableAttributedString * string = [[NSMutableAttributedString alloc]initWithString:cell.lbl_disc.text];
NSRange range=[cell.lbl_disc.text rangeOfString:_search_bar.text];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor yellowColor] range:range];
[self.textToSpeak setAttributedText:string];
use this method:
- (NSMutableAttributedString*) setColor:(UIColor*)color forWord:(NSString*)word inText:(NSMutableAttributedString*)string {
NSUInteger count = 0, length = [string length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound)
{
range = [[string string] rangeOfString:word options:0 range:range];
if(range.location != NSNotFound) {
[string setTextColor:color range:NSMakeRange(range.location, [word length])];
range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
count++;
}
}
return string;
}
and in your tableview cell call this
cell.lbl_disc.text= [self setColor:[UIColor yellowColor] forWord:_search_bar.text inText:[[NSMutableAttributedString alloc] initWithAttributedString:[NSString stringWithFormat:#"%#",[arrDescription objectAtIndex:indexPath.row]]]];
I want to be able to change the text in my UITableView cells when they are tapped on (selected/highlighted). The content from each cell is derived from an NSAttributedString. Here is that code:
-(NSAttributedString*)formattedSubject:(int)state {
if(formattedSubject!=nil) return formattedSubject;
NSDictionary *boldStyle = [[NSDictionary alloc] init];
if(state==1) {
boldStyle = #{NSFontAttributeName:[UIFont fontWithName:#"Helvetica-Bold" size:16.0],NSForegroundColorAttributeName:[UIColor colorWithRed:0.067 green:0.129 blue:0.216 alpha:1.0]};
}
else {
boldStyle = #{NSFontAttributeName:[UIFont fontWithName:#"Helvetica-Bold" size:16.0],NSForegroundColorAttributeName:[UIColor whiteColor]};
}
NSDictionary* normalStyle = #{NSFontAttributeName: [UIFont fontWithName:#"Helvetica" size:14.0]};
NSMutableAttributedString* articleAbstract = [[NSMutableAttributedString alloc] initWithString:subject];
[articleAbstract setAttributes:boldStyle range:NSMakeRange(0, subject.length)];
[articleAbstract appendAttributedString:[[NSAttributedString alloc] initWithString:#"\n"]];
int startIndex = [articleAbstract length];
NSTimeInterval _interval=[datestamp doubleValue];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:_interval];
NSDateFormatter *_formatter=[[NSDateFormatter alloc]init];
[_formatter setDateFormat:#"MM/dd/yy"];
NSString* description = [NSString stringWithFormat:#"By %# on %#",author,[_formatter stringFromDate:date]];
[articleAbstract appendAttributedString:[[NSAttributedString alloc] initWithString: description]];
[articleAbstract setAttributes:normalStyle range:NSMakeRange(startIndex, articleAbstract.length - startIndex)];
formattedSubject = articleAbstract;
return formattedSubject;
}
As you can see, I would like the boldStyle text to be a certain color (given by [UIColor colorWithRed:0.067 green:0.129 blue:0.216 alpha:1.0]) when the state is "1", and white otherwise. I've currently tried the following modifications in cellForRowAtIndexPath, as well as didSelectRowAtIndexPath:
cellForRowAtIndexPath:
NSIndexPath *path = [tableView indexPathForSelectedRow];
if(path) {
cell.textLabel.attributedText = [news formattedSubject:1];
}
else {
cell.textLabel.attributedText = [news formattedSubject:0];
}
What I am doing here is checking if a cell is selected, and if so then I changed that cell's "attributedText" to the "0" format. However, this didn't work, and I suspected it was because the modification had to be made when the cell was actually selected. So I tried the following in didSelectRowAtIndexPath:
didSelectRowAtIndexPath:
News *news = newsArray[indexPath.row];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.attributedText = [news formattedSubject:0];
However, it seems like the change is never made. I put an NSLog in the "else" part of the boldStyle if/else statement, and it was never written to the console.
Neither of my attempts at a solution have worked, and I've run out of ideas. How can I get the NSAttributedString to change when a cell is highlighted?
Update: It's also interesting that normalStyle text, which is by default black, does turn white when the cell is highlighted/selected when I add cell.textLabel.highlightedTextColor = [UIColor whiteColor]; in cellForRowAtIndexPath, but boldStyle text does not.
I have problem the same, and..
cell.textLabel.enable = NO;
It just resolved
In your cellForRowAtIndexPath method you are checking if a selectedIndexPath in this tableView exists.
NSIndexPath *path = [tableView indexPathForSelectedRow];
if(path) {
I think you want to compare your indexPath and your selectedIndexPath. You should use isEqual: for that.
NSIndexPath *selectedIndexPath = [tableView indexPathForSelectedRow];
if([selectedIndexPath isEqual:indexPath]) {
I have a custom UITableView cell set up in my UITableView like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"CELL_IDENTIFIER";
SGCustomCell *cell = (SGCustomCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) cell = [[SGCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
cell = [self customizedCell:cell withPost:[postsArray objectAtIndex:indexPath.row]];
return cell;
}
I set up the cell like this (specifically setting the UITextView.text to nil - as noted in this answer):
descriptionLabel.text = nil;
descriptionLabel.text = post.postDescription;
descriptionLabel.frame = CGRectMake(leftMargin - 4, currentTitleLabel.frame.origin.y + currentTitleLabel.frame.size.height + 10, self.frame.size.width - topMargin * 3, 100);
[descriptionLabel sizeToFit];
The cells are 100% reusable and UITextView is inited like this (as you see, nothing special):
descriptionLabel = [[UITextView alloc] init];
descriptionLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:11];
descriptionLabel.editable = NO;
descriptionLabel.scrollEnabled = NO;
descriptionLabel.dataDetectorTypes = UIDataDetectorTypeLink;
descriptionLabel.frame = CGRectMake(leftMargin, currentTitleLabel.frame.origin.y + currentTitleLabel.frame.size.height + 10, self.frame.size.width - topMargin * 3, 10);
[self addSubview:descriptionLabel];
But when the table has around 50 cells and when I scroll it fast I get the following crash:
Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds'
Which is absolutely ridiculous - I comment out this line - descriptionLabel.dataDetectorTypes = UIDataDetectorTypeLink; and the app stops crashing! I've spent hours trying to figure out what the problem was and now I simply get this.
Tested on iOS 7.0.3
The crash happens when two cells with data type are being dequeued while
using the same cell identifier.
It seems to be a bug in iOS, but Apple may have good reasons to implement it this way.
(memory wise)
And so the only 100% bullet proof solution is to provide a unique identifier for cells
containing data types.
This doesn't mean you will set a unique identifier to all cells in your table, of course,
as it will eat up too much memory and your table scroll will be really slow.
You can use NSDataDetector to determine if a matched type was found on your text,
and only then save the found object as the cell identifier, like so:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *row = [self.dataSource objectAtIndex:indexPath.row];
static NSDataDetector *detector = nil;
if (!detector)
{
NSError *error = NULL;
detector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink | NSTextCheckingTypePhoneNumber error:&error];
}
NSTextCheckingResult *firstDataType = [detector firstMatchInString:row
options:0
range:NSMakeRange(0, [row length])];
NSString *dataTypeIdentifier = #"0";
if (firstDataType)
{
if (firstDataType.resultType == NSTextCheckingTypeLink)
dataTypeIdentifier = [(NSURL *)[firstDataType URL] absoluteString];
else if (firstDataType.resultType == NSTextCheckingTypePhoneNumber)
dataTypeIdentifier = [firstDataType phoneNumber];
}
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell_%#", dataTypeIdentifier];
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
...
Note: Initializing NSDataDetector *detector as static
rather than initialize it for each cell improves performance.
I could reproduce your crash.
Implementing the following method within the TableViewCell subclass
- (void)prepareForReuse
{
[super prepareForReuse];
[descriptionLabel setDataDetectorTypes: UIDataDetectorTypeNone];
}
and add following call within - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath before setting the text:
[descriptionLabel setDataDetectorTypes: UIDataDetectorTypeLink];
worked for me. Maybe it cancels ongoing drawing inside the textview and is avoiding the crash that way.
edit: Calling [descriptionLabel setDataDetectorTypes: UIDataDetectorTypeNone]; and [descriptionLabel setDataDetectorTypes: UIDataDetectorTypeLink]; just before setting the text also seems to fix the crash
Providing you are using iOS6 or above, you can use an NSDataDetector to make an attributable string and use that as your TextView text. A modified version of the following method is what we are going to be using. The method takes a string and some already predefined attributes (like font and text color), and will stop after the 100th link. It has some problems multiple phone numbers, though. You need to define your own code for URL escapping the address. The the NSDataDetector bit was taken from Apple's NSDataDetector reference: https://developer.apple.com/librarY/mac/documentation/Foundation/Reference/NSDataDetector_Class/Reference/Reference.html
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string attributes:attributes];
__block NSUInteger count = 0;
if (!_dataDetector)
{
NSError *error = nil;
_dataDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeAddress | NSTextCheckingTypePhoneNumber | NSTextCheckingTypeLink
error:&error];
}
[_dataDetector enumerateMatchesInString:string
options:0
range:NSMakeRange(0, [string length])
usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){
NSRange matchRange = [match range];
if ([match resultType] == NSTextCheckingTypeLink)
{
NSURL *url = [match URL];
if (url)
{
[attributedString addAttribute:NSLinkAttributeName value:url range:matchRange];
}
}
else if ([match resultType] == NSTextCheckingTypePhoneNumber)
{
NSString *phoneNumber = [NSString stringWithFormat:#"tel:%#",[match phoneNumber]];
NSURL *url = [NSURL URLWithString:phoneNumber];
if (url)
{
[attributedString addAttribute:NSLinkAttributeName value:url range:matchRange];
}
}
else if ([match resultType] == NSTextCheckingTypeAddress)
{
//Warning! You must URL escape this!
NSString *address = [string substringWithRange:matchRange];
//Warning! You must URL escape this!
NSString *urlString = [NSString stringWithFormat:#"http://maps.apple.com/?q=%#",address];
NSURL *url = [NSURL URLWithString:urlString];
if (url)
{
[attributedString addAttribute:NSLinkAttributeName value:url range:matchRange];
}
}
if (++count >= 100) *stop = YES;
}];
return attributedString;
I have a UITableView which is populated with some parsed JSON twitter data. The intent is to have the user select the a row, and have the data passed to a modalViewController, which in this case is a map displaying coordinate and annotation information.
In the debug console I can see the data loaded into each visible UITableViewCell, plus the first one off screen (last loaded). When I run the app, and attempt to select a row, no matter which row I select, the data from the last loaded cell is always the data passed to the modalViewController.
I have logged to ensure the correct row is selected (it is) but no matter which row is selected, the last data loaded is always the data that is pushed.
First the Data Source Methods
#pragma mark -
#pragma mark UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSUInteger count = [self.results count];
return count > 0 ? count : 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ResultCellIdentifier = #"ResultCell";
static NSString *LoadCellIdentifier = #"LoadingCell";
NSUInteger count = [self.results count];
if ((count == 0) && (indexPath.row == 0)) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:LoadCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:LoadCellIdentifier];
cell.textLabel.textAlignment = UITextAlignmentCenter;
}
if (self.connection) {
cell.textLabel.text = #"Loading...";
} else {
cell.textLabel.text = #"Not available";
}
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ResultCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:ResultCellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont systemFontOfSize:14.0];;
}
UIImage *image = [UIImage imageNamed:#"medicaltag.png"];
cell.imageView.image = image;
// Begin UITableCell Data Formatting
NSDictionary *tweet = [self.results objectAtIndex:indexPath.row];
NSString* tweetText = [tweet objectForKey:#"text"];
if ([tweetText rangeOfString:#" *** "].location !=NSNotFound) {
NSArray *textItems = [tweetText componentsSeparatedByString:#" *** "];
NSLog(#"%#", textItems);
callAddress = [textItems objectAtIndex:0];
callAddress = [callAddress stringByReplacingOccurrencesOfString:#" , " withString:#", "];
callType = [textItems objectAtIndex:1];
NSLog(#"%#", callType);
NSLog(#"%#", callAddress);
NSString *latitude = [textItems objectAtIndex:2];
NSString *latStringPt1 = [[NSString alloc] init];
NSString *latStringPt2 = [[NSString alloc] init];
NSString *longitude = [textItems objectAtIndex:3];
longitude = [longitude stringByReplacingOccurrencesOfString:#"- " withString:#"-"];
NSString *lonStringPt1 = [[NSString alloc] init];
NSString *lonStringPt2 = [[NSString alloc] init];
int latStringLen = [latitude length];
int lonStringLen = [longitude length];
NSLog(#"The value of integer num is %i", latStringLen);
latStringPt1 = [latitude substringWithRange:NSMakeRange(0,latStringLen-6)];
latStringPt2 = [latitude substringFromIndex:latStringLen-6];
combinedLatString = [latStringPt1 stringByAppendingString:#"."];
combinedLatString = [combinedLatString stringByAppendingString:latStringPt2];
lonStringPt1 = [longitude substringWithRange:NSMakeRange(0,lonStringLen-6)];
lonStringPt2 = [longitude substringFromIndex:lonStringLen-6];
combinedLonString = [lonStringPt1 stringByAppendingString:#"."];
combinedLonString = [combinedLonString stringByAppendingString:lonStringPt2];
NSLog(#"%#", combinedLatString);
NSLog(#"%#", combinedLonString);
}
cell.textLabel.text = [NSString stringWithFormat:#"%#", callAddress];
cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", callType];
cell.detailTextLabel.font = [UIFont systemFontOfSize:14];
return cell;
}
Now the Delegate Method
#pragma mark -
#pragma mark Table View Delegate Methods*
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
NSLog(#"%i", row);
CallMapViewController *mapVC = [[CallMapViewController alloc] initWithNibName:#"CallMapViewController" bundle:[NSBundle mainBundle]];
mapVC.annotCallType = callType;
mapVC.annotCallAddress = callAddress;
NSLog(#"%#", mapVC.annotCallType);
NSLog(#"%#", mapVC.annotCallAddress);
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *lat = [f numberFromString:combinedLatString];
NSNumber *lon = [f numberFromString:combinedLonString];
mapVC.annotLatCoord = lat;
mapVC.annotLonCoord = lon;
NSLog(#"%#", lat);
NSLog(#"%#", lon);
NSLog(#"%#", callType);
NSLog(#"%#", callAddress);
[self presentModalViewController:mapVC animated:YES];
}
You already have your tweet data stored in your viewController's property results, so you just need to grab the data from there and parse it again (as Daryl Teo mentions) in didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString* tweetText = [[self.results objectAtIndex:indexPath.row] objectForKey:#"text"];
if ([tweetText rangeOfString:#" *** "].location != NSNotFound) {
NSArray *textItems = [tweetText componentsSeparatedByString:#" *** "];
CallMapViewController *mapVC = [[CallMapViewController alloc] initWithNibName:#"CallMapViewController" bundle:[NSBundle mainBundle]];
mapVC.callAddress = [[textItems objectAtIndex:0] stringByReplacingOccurrencesOfString:#" , " withString:#", "];
mapVC.callType = [textItems objectAtIndex:1];
[self presentModalViewController:mapVC animated:YES];
}
}
You get [indexPath row] but you don't use it.
And you've got "callType" and "callAddress" which aren't within the scope of the delegate method. They exist as instance variables of the viewController, and you set their values as you're creating the cells. That's why their values are always the values of the last cell.
You need to store the data in memory, so that you can reference it when you get the row from indexPath.
NSInteger row = [indexPath row];
NSString *tweetText = [tweetsStorageArray objectAtIndex: row];
/* Parse Tweet Text again */
You can either store tweets as text, or create a storage class and store that.
From what I can see in the method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
You take the [indexPath row]; but you don't chose your data base on that.
I see that in your delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath () you are only accessing the selected row variable for NSLog messages.
You would probably need to access the cell using UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath] and its contents using callType = cell.detailTextLabel.text;and callAddress = cell.textLabel.text;