I am working on chat application. Actually i have 3 arrays. First array stores user name and second array stores chat message and third array stores images. I am picking image from photo gallery.
When user sends any message to the chat wall I display message in bubble.
So I'm writing some conditions like the below:
if arr2 value is not null then displaying chat message
if arr3 value is not null displaying image in chat bubble
if arr2 value is null then i want to hide lbldesc and show only imv gallery image
if arr3 value is null then hide imv gallery image and enable lblDesc
But i got exception like this:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** NSAllocateMemoryPages(4294967295) failed'`
Here is my code:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.selectionStyle=UITableViewCellSelectionStyleNone;
if (itemsDataArr.count>0) {
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(35, 3, 250, 80)];
imgView.image = [UIImage imageNamed:#"speech-bubble-2-hi.png"];
imgView.layer.borderColor = [UIColor clearColor].CGColor;
imgView.tag = 5;
[cell.contentView addSubview:imgView];
NSArray *arr1=[[NSArray alloc]init];
arr1=[itemsUserNameArr objectAtIndex:indexPath.row];
NSString *strval=[arr1 objectAtIndex:0];
lblTitle=[[UILabel alloc]initWithFrame:CGRectMake(50, 5, 150, 20)];
lblTitle.highlightedTextColor=[UIColor whiteColor];
[cell.contentView addSubview:lblTitle];
[lblTitle setFont:[UIFont boldSystemFontOfSize:14]];
lblTitle.text=strval;
[imgView addSubview:lblTitle];
NSArray *arr2=[[NSArray alloc]init];
arr2=[itemsDataArr objectAtIndex:indexPath.row];
NSArray *arr3=[[NSArray alloc]init];
arr3=[itemImgArray objectAtIndex:indexPath.row];
if(![arr2 isEqual:#""])
{
NSString *strmsg=[arr2 objectAtIndex:0];
lblDesc=[[UILabel alloc]initWithFrame:CGRectMake(50, 22, 300, 20)];
lblDesc.highlightedTextColor=[UIColor whiteColor];
lblDesc.font=[UIFont systemFontOfSize:12.0];
[cell.contentView addSubview:lblDesc];
[lblDesc setHidden:NO];
lblDesc.text=strmsg;
[imgView addSubview:lblDesc];
// imv.hidden=YES;
// [imv setHidden:true];
}
arr3=[itemImgArray objectAtIndex:indexPath.row];
if(![arr3 isEqual:nil])
{
NSString *strImg=[arr3 objectAtIndex:0];
NSData *data = [[NSData alloc] initWithData:[NSData dataFromBase64String:strImg]];
//Now data is decoded. You can convert them to UIImage
imv = [[UIImageView alloc]initWithFrame:CGRectMake(93,12, 50, 50)];
imv.image=[UIImage imageWithData:data];
[imgView addSubview:imv];
[lblDesc setHidden:YES];
// lblDesc.hidden=YES;
}
}
return cell;
}
I've used PTSMessagingCell from here:
I've used messages array for texts/images. This is a ruf sample that may help you.
#import "ViewController.h"
#import "PTSMessagingCell.h"
#interface ViewController ()
{
NSMutableArray *messages;
UITextView *sendMsg;
UITableView *chatTable;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
messages = [[NSMutableArray alloc] initWithObjects:#"Hello",[UIImage imageNamed:#"download.jpeg"],#"Check This Out", nil];
chatTable = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-100)];
chatTable.delegate = self;
chatTable.dataSource = self;
chatTable.separatorColor = [UIColor clearColor];
[self.view addSubview:chatTable];
chatTable.backgroundColor = [UIColor clearColor];
sendMsg = [[UITextView alloc]initWithFrame:CGRectMake(0, chatTable.frame.size.height, self.view.frame.size.width-100, 100)];
sendMsg.textColor = [UIColor blackColor];
sendMsg.delegate = self;
sendMsg.backgroundColor = [UIColor whiteColor];
sendMsg.layer.cornerRadius = 3.0f;
[self.view addSubview:sendMsg];
UIButton *sendMsgbtn = [[UIButton alloc]initWithFrame:CGRectMake(sendMsg.frame.size.width, chatTable.frame.size.height, 100, 100)];
[sendMsgbtn setTitle:#"SEND" forState:UIControlStateNormal];
sendMsgbtn.backgroundColor = [UIColor redColor];
[sendMsgbtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[sendMsgbtn addTarget:self action:#selector(sendClicked) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:sendMsgbtn];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapReceived:)];
[tapGestureRecognizer setDelegate:self];
[chatTable addGestureRecognizer:tapGestureRecognizer];
}
-(void)sendClicked{
[sendMsg resignFirstResponder];
[chatTable reloadData];
}
#pragma mark - TableView Delegate and DataSource Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [messages count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
/*This method sets up the table-view.*/
static NSString* cellIdentifier = #"messagingCell";
PTSMessagingCell * cell = (PTSMessagingCell*) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[PTSMessagingCell alloc] initMessagingCellWithReuseIdentifier:cellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[messages objectAtIndex:indexPath.row] isKindOfClass:[UIImage class]]) {
return [(UIImage *)[messages objectAtIndex:indexPath.row] size].height;
}
else{
const char *jsonString = [[NSString stringWithFormat:#"%#",[messages objectAtIndex:indexPath.row]] UTF8String];
NSData *jsonData = [NSData dataWithBytes:jsonString length:strlen(jsonString)];
NSString *goodMsg = [[NSString alloc] initWithData:jsonData encoding:NSNonLossyASCIIStringEncoding];
CGSize messageSize = [PTSMessagingCell messageSize:goodMsg];
NSLog(#"%f",messageSize.height + 2*[PTSMessagingCell textMarginVertical] + 40.0f);
return messageSize.height + 2*[PTSMessagingCell textMarginVertical] + 40.0f;
}
}
-(void)configureCell:(id)cell atIndexPath:(NSIndexPath *)indexPath {
if (messages.count>0) {
PTSMessagingCell* ccell = (PTSMessagingCell*)cell;
if ([[messages objectAtIndex:indexPath.row] isKindOfClass:[UIImage class]]) {
ccell.sent = YES;
ccell.avatarImageView.image = [UIImage imageNamed:[messages objectAtIndex:indexPath.row]];
ccell.messageLabel.text = #"";
}
else{
ccell.sent = YES;
const char *jsonString = [[NSString stringWithFormat:#"%#",[messages objectAtIndex:indexPath.row]] UTF8String];
NSData *jsonData = [NSData dataWithBytes:jsonString length:strlen(jsonString)];
NSString *goodMsg = [[NSString alloc] initWithData:jsonData encoding:NSNonLossyASCIIStringEncoding];
ccell.messageLabel.text = [messages objectAtIndex:indexPath.row];
}
ccell.timeLabel.text = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterFullStyle];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapReceived:)];
[tapGestureRecognizer setDelegate:self];
[ccell addGestureRecognizer:tapGestureRecognizer];
}
}
-(void)tapReceived:(UITapGestureRecognizer *)tapGestureRecognizer
{
// do something, like dismiss your view controller, picker, etc., etc.
[sendMsg resignFirstResponder];
}
Hope this helps.
Create a custom cell and load images in background thread will give better UI performance
Related
New to iOS...i am trying to do a search with a downloaded NSMutableArray table using searchbar or do need to get search from mysql table...its driving me nuts here is code below...any help would be appreciated
#import "VendorViewController.h"
#import "VendLocation.h"
#import "VendorDetailController.h"
#interface VendorViewController ()
{
VendorModel *_VendorModel; NSMutableArray *_feedItems; VendLocation *_selectedLocation; UIRefreshControl *refreshControl;
}
#property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
#end
#implementation VendorViewController
//#synthesize item;
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Vendors";
self.searchBar.hidden = YES;
self.searchBar.delegate = self;
self.searchBar.barTintColor = [UIColor clearColor];
//self.searchBar.barTintColor = [UIColor orangeColor];
_feedItems = [[NSMutableArray alloc] init];
_VendorModel = [[VendorModel alloc] init];
_VendorModel.delegate = self;
[_VendorModel downloadItems];
#pragma mark Bar Button
UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(searchButton:)];
NSArray *actionButtonItems = #[searchItem];
self.navigationItem.rightBarButtonItems = actionButtonItems;
#pragma mark Table Refresh
UIView *refreshView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
[self.tableView insertSubview:refreshView atIndex:0]; //the tableView is a IBOutlet
refreshControl = [[UIRefreshControl alloc] init];
refreshControl.backgroundColor = [UIColor grayColor];
refreshControl.tintColor = [UIColor whiteColor];
[refreshControl addTarget:self action:#selector(reloadDatas) forControlEvents:UIControlEventValueChanged];
NSMutableAttributedString *refreshString = [[NSMutableAttributedString alloc] initWithString:#"Refreshing"];
//add date to refresh
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM d, h:mm a"];
NSString *lastUpdated = [NSString stringWithFormat:#"Last updated on %#", [formatter stringFromDate:[NSDate date]]];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdated];
[refreshString addAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]} range:NSMakeRange(0, refreshString.length)];
[refreshView addSubview:refreshControl];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
**#pragma mark - Search
- (void)searchButton:(id)sender{
[self.searchBar becomeFirstResponder];
self.searchBar.hidden = NO;
//[self.listTableView resignFirstResponder];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
self.searchBar.hidden = YES;
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if(searchText.length == 0)
{
isFilltered = NO;
} else {
isFilltered = YES;
filteredString = [[NSMutableArray alloc]init];
for(NSString *vendorName in _feedItems)
{
NSRange vendorNameRange = [vendorName rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(vendorNameRange.location != NSNotFound) {
[filteredString addObject:vendorName];
}
}
}
[self.listTableView reloadData];
}**
#pragma mark - Table
-(void)reloadDatas {
[refreshControl endRefreshing];
}
-(void)itemsDownloaded:(NSMutableArray *)items
{ // This delegate method will get called when the items are finished downloading
_feedItems = items;
[self.listTableView reloadData];
}
#pragma mark Table Delete Button
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleDelete;
}
- (void) setEditing:(BOOL)editing
animated:(BOOL)animated{
[super setEditing:editing
animated:animated];
[self.listTableView setEditing:editing
animated:animated];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_feedItems removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView reloadData];
/*
NSError *error = nil;
if (![tableView save:&error]) {
NSLog(#"Can't Delete! %# %#", error, [error localizedDescription]);
return;
} */
}
}
#pragma mark TableView Delegate Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (isFilltered) {
return [filteredString count];
}
return _feedItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
VendLocation *item = _feedItems[indexPath.row];
static NSString *CellIdentifier = #"BasicCell";
UITableViewCell *myCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
myCell.layer.cornerRadius = 5;
myCell.layer.masksToBounds = YES;
if (myCell == nil) {
myCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; }
if (!isFilltered) {
myCell.textLabel.text = item.vendorName;
myCell.detailTextLabel.text = item.vendorNo;
//Retreive an image
UIImage *myImage = [UIImage imageNamed:#"DemoCellImage"];
[myCell.imageView setImage:myImage];
} else {
myCell.textLabel.text = [filteredString objectAtIndex:indexPath.row];
myCell.detailTextLabel.text = nil;
}
return myCell;
}
#pragma mark Tableheader
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 55.0;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSString *newString = [NSString stringWithFormat:#"VENDOR \n%lu", (unsigned long) _feedItems.count];
NSString *newString1 = [NSString stringWithFormat:#"NASDAQ \n4,727.35"];
NSString *newString2 = [NSString stringWithFormat:#"DOW \n17,776.80"];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 0)];
tableView.tableHeaderView = view; //makes header move with tablecell
[view setBackgroundColor:[UIColor clearColor]];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(12, 3, tableView.frame.size.width, 45)];
[label setFont:[UIFont systemFontOfSize:12]];
[label setTextColor:[UIColor whiteColor]];
label.numberOfLines = 0;
NSString *string = newString;
[label setText:string];
[view addSubview:label];
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(12, 45, 60, 1.5)];
separatorLineView.backgroundColor = [UIColor redColor];
[view addSubview:separatorLineView];
UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(85, 3, tableView.frame.size.width, 45)];
label1.numberOfLines = 0;
[label1 setFont:[UIFont systemFontOfSize:12]];
[label1 setTextColor:[UIColor whiteColor]];
NSString *string1 = newString1;
[label1 setText:string1];
[view addSubview:label1];
UIView* separatorLineView1 = [[UIView alloc] initWithFrame:CGRectMake(85, 45, 60, 1.5)];
separatorLineView1.backgroundColor = [UIColor redColor];
[view addSubview:separatorLineView1];
UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(158, 3, tableView.frame.size.width, 45)];
label2.numberOfLines = 0;
[label2 setFont:[UIFont systemFontOfSize:12]];
[label2 setTextColor:[UIColor whiteColor]];
NSString *string2 = newString2;
[label2 setText:string2];
[view addSubview:label2];
UIView* separatorLineView2 = [[UIView alloc] initWithFrame:CGRectMake(158, 45, 60, 1.5)];
separatorLineView2.backgroundColor = [UIColor redColor];
[view addSubview:separatorLineView2];
return view;
}
here is my header
#import <UIKit/UIKit.h>
#import "VendorModel.h"
#interface VendorViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, VendorModelProtocol>
{
// NSMutableArray *_feedItems;
NSMutableArray *filteredString;
BOOL isFilltered;
}
#property (weak, nonatomic) IBOutlet UITableView *listTableView;
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
Changed Code to textDidChange
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if(searchText.length == 0)
{
isFilltered = NO;
} else {
isFilltered = YES;
filteredString = [[NSMutableArray alloc]init];
for(VendLocation* vendor in _feedItems)
{
NSRange stringRange = [vendor.vendorName rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location != NSNotFound) {
[filteredString addObject:vendor];
}
}
}
[self.tableView reloadData];
}
i changed filter too this code still no luck hit a key and crash
if(searchText.length == 0)
{
isFilltered = NO;
[filteredString removeAllObjects];
[filteredString addObjectsFromArray:_feedItems];
} else {
isFilltered = YES;
// filteredString = [[NSMutableArray alloc]init];
[filteredString removeAllObjects];
for(NSString* string in _feedItems)
{
NSRange stringRange = [string rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location != NSNotFound) {
[filteredString addObject:string];
}
}
}
[self.tableView reloadData];
If you already have a downloaded NSMutableArray with data in it then your search can consist of merely searching through the array and filtering out entries that do not match. You do not have to go back to MySQL.
My Parse cloud code sends back JSON to my iOS app with the following structure:
What I want to do is iterate through this and create a new section in the UITableView for every object in this matchCenterArray.
In this instance, there are three objects in the array, each contains a Top 3 NSDictionary whose value is an array of 3 items, each of which is yet another array of properties. As you can see, I want it set up so that each section has 3 cells, one for each of the top 3 items of that respective matchCenterArray object. I then want it to pull the properties of each item and display it in each cell as the texLabel, detailTextLabel, and thumbnail.
I've tried using a for loop as a solution, but this displays the same item in all cells of the array. This is probably because I'm only looping through matchCenterArray objects, but not additionally looping through items in those objects, as can be seen here:
cell.textLabel.text = [[[[_matchCenterArray objectAtIndex:i] objectForKey:#"Top 3"] objectAtIndex:0]objectForKey:#"Title"];
What I was thinking of doing is nesting a for loop within this one, in place of objectAtIndex:0, but sending a message to a for loop doesn't work.
MatchCenterViewController.m:
#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>
#interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UITableView *matchCenter;
#end
#implementation MatchCenterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewCellStyleSubtitle];
self.matchCenter.frame = CGRectMake(0,50,320,self.view.frame.size.height-100);
_matchCenter.dataSource = self;
_matchCenter.delegate = self;
[self.view addSubview:self.matchCenter];
_matchCenterArray = [[NSArray alloc] init];
}
- (void)viewDidAppear:(BOOL)animated
{
self.matchCenterArray = [[NSArray alloc] init];
[PFCloud callFunctionInBackground:#"MatchCenterTest"
withParameters:#{
#"test": #"Hi",
}
block:^(NSArray *result, NSError *error) {
if (!error) {
_matchCenterArray = result;
[_matchCenter reloadData];
NSLog(#"Result: '%#'", result);
}
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return _matchCenterArray.count;
}
//the part where i setup sections and the deleting of said sections
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 21.0f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 21)];
headerView.backgroundColor = [UIColor lightGrayColor];
// _searchTerm = [[self.matchCenterArray firstObject] objectForKey:#"Search Term"];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(8, 0, 250, 21)];
// headerLabel.text = [NSString stringWithFormat:#"%#", searchTerm];
// headerLabel.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
// headerLabel.textColor = [UIColor whiteColor];
headerLabel.backgroundColor = [UIColor lightGrayColor];
[headerView addSubview:headerLabel];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag = section + 1000;
button.frame = CGRectMake(300, 2, 17, 17);
[button setImage:[UIImage imageNamed:#"xbutton.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(deleteButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[headerView addSubview:button];
return headerView;
}
- (IBAction)deleteButtonPressed:(UIButton *)sender {
NSLog(#"Search Term: '%#'", _searchTerm);
[PFCloud callFunctionInBackground:#"deleteFromMatchCenter"
withParameters:#{
#"searchTerm": _searchTerm,
}
block:^(NSDictionary *result, NSError *error) {
if (!error) {
NSLog(#"Result: '%#'", result);
}
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Initialize cell
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
// if no cell could be dequeued create a new one
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
for (int i = 0; i<[_matchCenterArray count]; i++) {
// populate dictionary with results
//NSDictionary *matchCenterDictionary= [_matchCenterArray objectAtIndex:indexPath.row];
// title of the item
cell.textLabel.text = [[[[_matchCenterArray objectAtIndex:i] objectForKey:#"Top 3"] objectAtIndex:0]objectForKey:#"Title"];
cell.textLabel.font = [UIFont boldSystemFontOfSize:12];
// price of the item
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#", [[[[_matchCenterArray objectAtIndex:i] objectForKey:#"Top 3"] objectAtIndex:0]objectForKey:#"Price"]];
cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0f green:127/255.0f blue:31/255.0f alpha:1.0f];
// image of the item
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[[[_matchCenterArray objectAtIndex:i] objectForKey:#"Top 3"] objectAtIndex:0] objectForKey:#"Image URL"]]];
[[cell imageView] setImage:[UIImage imageWithData:imageData]];
//imageView.frame = CGRectMake(45.0,10.0,10,10);
}
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
Forget about the loops, the delegate method already run on a loop where the iteration number is equal to the datasource count.
numberOfSectionsInTableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return _matchCenterArray.count;
}
numberOfRowsInSection
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section{
return _matchCenterArray[section][#"Top 3"].count;
}
cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// Initialize cell
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
// if no cell could be dequeued create a new one
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
}
// title of the item
cell.textLabel.text = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Title"];
cell.textLabel.font = [UIFont boldSystemFontOfSize:12];
// price of the item
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#", _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Price"];
cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0f green:127/255.0f blue:31/255.0f alpha:1.0f];
// image of the item
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:_matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Image URL"]]];
[[cell imageView] setImage:[UIImage imageWithData:imageData]];
return cell;
}
Don't harcode your array count, if your json changes, your code will need to change.
In the future you should look into loading the images asynchronously using a library like SDWebImage in order to avoid lags.
cellForRowAtIndexPath: is called once per numberOfRowsInSection:
You need to add numberOfSections as well:
it should look like this:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Initialize cell
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
// if no cell could be dequeued create a new one
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// the following will set the cell attributes for cells in each section
// to customize per section, use indexPath.section to get which section you are at
// title of the item
cell.textLabel.text = [[[[_matchCenterArray objectAtIndex:indexPath.row objectForKey:#"Top 3"] objectAtIndex:0]objectForKey:#"Title"];
cell.textLabel.font = [UIFont boldSystemFontOfSize:12];
// price of the item
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#", [[[[_matchCenterArray objectAtIndex:indexPath.row] objectForKey:#"Top 3"] objectAtIndex:0]objectForKey:#"Price"]];
cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0f green:127/255.0f blue:31/255.0f alpha:1.0f];
// image of the item
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[[[_matchCenterArray objectAtIndex:indexPath.row] objectForKey:#"Top 3"] objectAtIndex:0] objectForKey:#"Image URL"]]];
[[cell imageView] setImage:[UIImage imageWithData:imageData]];
return cell;
}
Please refer to apple's tableView guide
I have a NSMutableArray in a view where I parse some JSON data to a Table View. I also have three buttons on the bottom: Button 1, Button 2, Button 3. If I select Button 2, the JSON data string changes to Link 2 etc...
Now, when I click on a cell, the value (text) passes to a UITextView in the Second View Controller. But what I want, is to also pass which button that was pressed, so the string name to the UITextView parses correct. Because now, when I select for example button 2 and click on a cell, the Text View on Second View Controller gets blank, because I only set the string name to #"message", and the string name for the text when selected Button 2 is #"tweet".
Here's my code:
#interface DEMOSecondViewController ()
#end
#implementation DEMOSecondViewController
#synthesize tableView = _tableView, activityIndicatorView = _activityIndicatorView;
#synthesize fontForCellText;
#synthesize btnFaceBook, btnTwitter, btnTwitter2;
#synthesize strURLToLoad;
#synthesize movies;
- (IBAction)showButtonMenu {
[self.frostedViewController presentMenuViewController];
}
- (void)refresh:(UIRefreshControl *)refreshControl {
[refreshControl endRefreshing];
}
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl setTintColor:[UIColor greenColor]];
[refreshControl addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
[self.tableView addSubview:refreshControl];
strURLToLoad = [[NSMutableString alloc] init];
[btnFaceBook setTitle:#"link-1.com/json.php" forState:UIControlStateDisabled];
[btnTwitter setTitle:#"link-2.com/json.php" forState:UIControlStateDisabled];
[btnTwitter2 setTitle:#"link-3.com/json.php" forState:UIControlStateDisabled];
[btnFaceBook setBackgroundImage:[UIImage imageNamed:#"tab_selected.png"] forState:UIControlStateNormal];
[btnFaceBook setBackgroundImage:[UIImage imageNamed:#"tab_unselected.png"] forState:UIControlStateSelected];
[btnTwitter setBackgroundImage:[UIImage imageNamed:#"tab_selected.png"] forState:UIControlStateNormal];
[btnTwitter setBackgroundImage:[UIImage imageNamed:#"tab_unselected.png"] forState:UIControlStateSelected];
[btnTwitter2 setBackgroundImage:[UIImage imageNamed:#"tab_selected.png"] forState:UIControlStateNormal];
[btnTwitter2 setBackgroundImage:[UIImage imageNamed:#"tab_unselected.png"] forState:UIControlStateSelected];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"PostsObject" owner:self options:nil];
PostsObject *cell = [nib objectAtIndex:0];
fontForCellText = cell.title.font;
cellTextWidth = cell.title.frame.size.width;
cellHeightExceptText = cell.frame.size.height - cell.title.frame.size.height;
[self.navigationController setNavigationBarHidden:YES];
self.tableView.separatorColor = [UIColor clearColor];
// Setting Up Activity Indicator View
self.activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
self.activityIndicatorView.color = [UIColor greenColor];
self.activityIndicatorView.hidesWhenStopped = YES;
self.activityIndicatorView.center = self.view.center;
[self.view addSubview:self.activityIndicatorView];
[self.activityIndicatorView startAnimating];
self.tableView.separatorColor = [UIColor clearColor];
// Initializing Data Source
movies = [[NSMutableArray alloc] init];
[self btnFromTabBarClicked:btnFaceBook];
}
- (void)loadJSONFromCurrentURL
{
[self.activityIndicatorView startAnimating];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:strURLToLoad]];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
[movies setArray:JSON];
[self.activityIndicatorView stopAnimating];
[self.tableView reloadData];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Request Failed with Error: %#, %#", error, error.userInfo);
}];
[operation start];
}
//This is where I change the data source when selecting a button
- (IBAction)btnFromTabBarClicked:(UIButton *)sender
{
btnFaceBook.selected = btnTwitter.selected = btnTwitter2.selected = NO;
sender.selected = YES;
[strURLToLoad setString:[sender titleForState:UIControlStateDisabled]];
[self loadJSONFromCurrentURL];
}
// Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return movies.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 0) {
static NSString *Identifier1 = #"TableHeaderView";
TableHeaderView *cell = [tableView dequeueReusableCellWithIdentifier:Identifier1];
if (cell == nil) {
NSArray *nib= [[NSBundle mainBundle] loadNibNamed:#"TableHeaderView" owner:self options:nil];
cell = (TableHeaderView *)[nib objectAtIndex:0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor = [UIColor clearColor];
return cell;
}
} else {
static NSString *Identifier2 = #"PostsObject";
PostsObject *cell = [tableView dequeueReusableCellWithIdentifier:Identifier2];
if (cell == nil) {
NSArray *nib= [[NSBundle mainBundle] loadNibNamed:#"PostsObject" owner:self options:nil];
cell = (PostsObject *)[nib objectAtIndex:0];
cell.backgroundColor = [UIColor clearColor];
}
NSDictionary *movie = [self.movies objectAtIndex:indexPath.row];
NSString *strText = [movie objectForKey:[self getTextKey]];
CGRect rect = cell.title.frame;
rect.size.height = [self getHeightForText:strText];
cell.title.frame = rect;
cell.title.text = strText;
cell.arrow.center = CGPointMake(cell.arrow.frame.origin.x, rect.origin.y + rect.size.height/2);
cell.published.text = [movie objectForKey:[self getPostedTime]];
cell.twitterName.text = [movie objectForKey:[self getTwitterName]];
return cell;
}
return 0;
}
//Here I am passing the selected cell data to (PostsNextView). I want to pass the string values of button 1, button 2 and button 3. How?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *movie = [self.movies objectAtIndex:indexPath.row];
PostsNextView *newView = [[PostsNextView alloc] init];
newView.theMovie = movie;
[self.navigationController pushViewController:newView animated:YES];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0) {
return 224;
} else {
NSDictionary *movie = [self.movies objectAtIndex:indexPath.row];
NSString *strText = [movie objectForKey:[self getTextKey]];
CGFloat cellHeight = cellHeightExceptText + [self getHeightForText:strText];
return cellHeight;
}
}
- (NSString *)getTextKey
{
return btnTwitter.selected?#"tweet":#"message";
}
- (NSString *)getPostedTime
{
return btnTwitter.selected?#"posted":#"published";
}
- (NSString *)getTwitterName
{
return btnTwitter2.selected?#"user":#"celebname";
}
- (CGFloat)getHeightForText:(NSString *)strText
{
CGSize constraintSize = CGSizeMake(cellTextWidth, MAXFLOAT);
CGSize labelSize = [strText sizeWithFont:fontForCellText constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
NSLog(#"labelSize.height = %f",labelSize.height);
return labelSize.height;
}
#end
As you can see in the first view, I have 3 different links I'm parsing. How can I set an if-statement in viewDidLoad in PostsNextView? Like, if the btnFacebook is selected: textView.text = [theMovie objectForKey:#"message"]; and if btnTwitter is selected: textView.text = [theMovie objectForKey:#"tweet"]; ?
Would really appreciate a solution!
Revised Answer (This will be high level):
Add Tag Values to each of your buttons
When a button is clicked you can get its tag with the getTag (also tag can be set with setTag) call - please check the API for details
As you are programatically loading your next view controller when you create it
PostsNextView *newView = [[PostsNextView alloc] init];
newView.theMovie = movie;
// You could add a call here to set the value
[newView setTheVaue:valueIWantToSet]
You would make a property called TheValue in your newView controller
When you actually make your call to change to the new view controller
[self.navigationController pushViewController:newView animated:YES];
The data value you desire will already be set.
How I can add prefix tel:65 to my phone number, that I fetched from address book in array.
If I do this in viewdidload it's getting null
NSURL *phoneUrl = [NSURL URLWithString:[NSString stringWithFormat:#"tel:%#", phoneNumbers]];
NSLog(#"Some Text %#", phoneUrl);
NSLog(#"Phone Numbers %#", phoneNumbers);
Here phoneNumbers is array with numbers per each contact
Udate:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"BG.jpg"]]];
[detailTableView setBackgroundColor:[UIColor clearColor]];
detailTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
ShadowTable *Shadow = [[ShadowTable alloc] init];
[Shadow ForTableView:detailTableView ForView:self.view HeaderAlpha:0.3 FooterAlpha:0.6];
for(int i = 0 ; i <[phoneNumbers count]; i++)
{
NSURL *phoneUrl = [NSURL URLWithString:[NSString stringWithFormat:#"tel:%#", [phoneNumbers objectAtIndex:i]]];
NSLog(#"Phone with URL %#", phoneUrl);
NSLog(#"Phone Numbers %#", phoneNumbers);
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [phoneTypes count];
}
- (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];
}
UILabel *typeLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 100, 40)];
typeLabel.text = [phoneTypes objectAtIndex:indexPath.row];
[typeLabel setBackgroundColor:[UIColor clearColor]];
[cell addSubview:typeLabel];
UILabel *numberLabel = [[UILabel alloc] initWithFrame:CGRectMake(130, 10, 170, 40)];
numberLabel.text = [phoneNumbers objectAtIndex:indexPath.row];
[numberLabel setBackgroundColor:[UIColor clearColor]];
[cell addSubview:numberLabel];
if (indexPath.row %2 == 0) {
cell.contentView.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1.0];
} else {
cell.contentView.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
}
//cell.textLabel.text = [phoneNumbers objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
You are using an array not a string. So you need to access all elements of array to add as suffix.
Use this :
for(int i = 0 ; i <[phoneNumbers count]; i++)
{
NSString *str = [#"tel:" stringByAppendingFormat:#"%#",[phoneNumbers objectAtIndex:i]];
str = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *phoneUrl = [NSURL URLWithString:str];
NSLog(#"Some Text %#", phoneUrl);
}
EDIT : Url was null because there were spaces in "2013-05-31 14:58:24.759 GTCallBack[8225:c07]" so encode it to remove spaces.
Hope it helps you.
I want to connect an my app to the database and display it in a Label.
I could connect my app to the database and display it in the UITableView.
This is what I have so far:
Viewontroller.h
#import <UIKit/UIKit.h>
#interface CartHistoryViewController : UITableViewController
{
NSMutableArray *arrayDataFromServer;
}
#end
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *strURL = [NSString stringWithFormat:#"http://localhost:8888/CartGet.php? choice=history"];
NSArray *arrayImagesNames = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURL]];
strURL = #"http://localhost:8888/CartGet.php?choice=historydate";
NSArray *arrayImagesPaths = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURL]];
// store the result in arrayDataFromServer
arrayDataFromServer = [[NSMutableArray alloc]init];
NSEnumerator *enumForNames = [arrayImagesNames objectEnumerator];
NSEnumerator *enumForPahts = [arrayImagesPaths objectEnumerator];
id objName, objPath;
while ( objName = [enumForNames nextObject]) {
objPath = [enumForPahts nextObject];
[arrayDataFromServer addObject:[NSDictionary dictionaryWithObjectsAndKeys:objName, #"name", objPath, #"path", nil]];
}
}
- (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];
}
cell.textLabel.text = [[arrayDataFromServer objectAtIndex:indexPath.row] objectForKey:#"name"];
[cell.textLabel setFont:[UIFont systemFontOfSize:20]];
cell.detailTextLabel.text = [[arrayDataFromServer objectAtIndex:indexPath.row] objectForKey:#"path"];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#",[[arrayDataFromServer objectAtIndex:indexPath.row] objectForKey:#"path"]]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [UIImage imageWithData:data];
cell.imageView.image = img;
return cell;
}
I want to be able to display it in a Label and in an ImageView instead of a cell. Please help.
Go to your Interface Builder choose your table view and make it Grouped TableView
add below code before your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrayDataFromServer count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 0;
}
// set header height of gropued tableview
-(CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section
{
return 120;//change this value if it is too big
}
//set header section labels
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSString * subject=[[arrayDataFromServer objectAtIndex:section] objectForKey:#"name"];//this line may give you error because of section easy to correct
UILabel *subjectLabel = [[UILabel alloc] initWithFrame:CGRectMake(45, 30, 100, 100)];
subjectLabel.textColor = [UIColor colorWithRed:0/256.0 green:84/256.0 blue:129/256.0 alpha:1.0];
subjectLabel.font = [UIFont fontWithName:#"Arial" size:25];
subjectLabel.text = subject;
subjectLabel.backgroundColor = [UIColor clearColor];
[subjectLabel sizeToFit];
// if you want to add image view create an imageview programatically here
// NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#",[[arrayDataFromServer objectAtIndex:section] objectForKey:#"path"]]];
//NSData *data = [NSData dataWithContentsOfURL:url];
//UIImage *img = [UIImage imageWithData:data];
// UIImageView *brickAnim = [[UIImageView alloc] initWithImage:img];
// Create header view and add label as a subview choose coordinates wisely
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100, 120, 100, G00)];
[view addSubview:subjectLabel];
//[view addSubview:brickAnim];
return view;
}