I have image URL strings in a database. Then I retrieve the images and add them to productimg_array. I need to show the images in table view cells. I used SDWebImage for download images from URL. But only one image displaying all the Cell.
const char *sql = "SELECT id,cat_id,product_image,order_by,description FROM product";
NSLog(#"sql is %s",sql);
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
// We "step" through the results - once for each row.
while (sqlite3_step(statement) == SQLITE_ROW) {
product_image = [[NSString alloc] initWithUTF8String: (const char *) sqlite3_column_text(statement, 2)];
NSLog(#"product_image is %#",product_image);
[productimg_array addObject:product_image];
NSLog(#"productimg_arr is %#",productimg_array);
}
}
sqlite3_finalize(statement);
Table view:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"productimg_array is %lu",(unsigned long)[productimg_array count]);
return [productimg_array 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];
}
for(int i=0; i<[productimg_array count];i++) {
[cell.imageView setImageWithURL:[NSURL URLWithString:[productimg_array objectAtIndex:i]]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Log output:
productimg_arr is (
"http://server.net/projects/View/images/img.png",
"http://server.net/projects/View/images/img1.png",
"http://server.net/projects/View/images/img2.png",
"http://server.net/projects/View/images/img3.png",
"http://server.net/projects/View/images/img4.png",
"http://server.net/projects/View/images/img5.png",
"http://server.net/projects/View/images/img6.png"
)
Do this:
[cell.imageView setImageWithURL:[NSURL URLWithString:[productimg_array objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Then you will get different images in all cells.
Remove for loop from cellForRoeAtIndexPath and use indexPath.row instead of i.
Replace :
for(int i=0; i<[productimg_array count];i++){
[cell.imageView setImageWithURL:[NSURL URLWithString:[productimg_array objectAtIndex:i]]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
}
By :
[cell.imageView setImageWithURL:[NSURL URLWithString:[productimg_array objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Related
I am developing IOS App, using Sqlite to Store data. Data can be shown on tableview and delete the row from table view and data can be remove form database sqlite. but when I delete row from tableview, app is crashing. And the error I am getting is :
Error:reason: 'Invalid update: invalid number of rows in section 0.
The number of rows contained in an existing section after the update
(9) must be equal to the number of rows contained in that section
before the update (9), plus or minus the number of rows inserted or
deleted from that section (0 inserted, 1 deleted) and plus or minus
the number of rows moved into or out of that section (0 moved in, 0
moved out).
Thanks in Advance
Code :
NSMutableArray *resultArray
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
UITableViewCell *cell = [_tableview dequeueReusableCellWithIdentifier:#"cell"];
dataBase *data = [_arr objectAtIndex:indexPath.row];
UILabel *name = (UILabel *)[cell viewWithTag:1];
name.text = data.name;
UILabel *department = (UILabel *)[cell viewWithTag:2];
department.text = data.department;
UILabel *year = (UILabel *)[cell viewWithTag:3];
year.text = data.year;
if (indexPath.row %2 ==1) //Use for color on tableview
cell.backgroundColor = [UIColor colorWithRed:.9 green:.9 blue:.9 alpha:1];
else
cell.backgroundColor = [UIColor colorWithRed:.8 green:.8 blue:.8 alpha:1];
return cell;
}
-(void)tableView:(UITableView *)_tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_tableView beginUpdates];
Sqlite *sqlite = [[Sqlite alloc]init];
[sqlite delete_profile:indexPath.row];
NSMutableArray *newA = [[sqlite resultArray] mutableCopy];
[newA removeObjectAtIndex:indexPath.row];
[_tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationRight];
[_tableView endUpdates];
}
[_tableView reloadData];
}
// Method to delete Row From Sqlite
-(void)delete_profile:(NSInteger)value
{
// _categoryArray = [[NSMutableArray alloc]init];
NSString *databasename=#"student.db"; // Your database Name.
NSArray * documentpath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSAllDomainsMask, YES);
NSString * DocDir=[documentpath objectAtIndex:0];
NSLog(#"%#",DocDir);
NSString * databasepath=[DocDir stringByAppendingPathComponent:databasename];
if (sqlite3_open([databasepath UTF8String], &database) == SQLITE_OK)
{
NSStringEncoding stringEncoding = NSUTF8StringEncoding;
NSString *sql = [NSString stringWithFormat:#"DELETE FROM studentsDetail WHERE regno=\"%ld\"",(long)value];
const char *sqlStatement = [sql cStringUsingEncoding:stringEncoding];
if (sqlite3_prepare_v2(database,
sqlStatement, -1, &statement, NULL) == SQLITE_OK)
{
//sqlite3_bind_int(statement, 1, value);
if (sqlite3_step(statement) == SQLITE_OK)
{
dataBase *base = [[dataBase alloc]init];
base.name = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
base.department = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 2)];
base.year = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 3)];
[_resultArray addObject:base];
}
}
else {
NSAssert1(0,#"Error preparing statement", sqlite3_errmsg(database));
}
}
}
No need for [_tableView reloadData]; after deleteRowsAtIndexPaths
Try this
-(void)tableView:(UITableView *)_tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
Sqlite *sqlite = [[Sqlite alloc]init];
[sqlite delete_profile:indexPath.row];
[resultArray removeObjectAtIndex:indexPath.row];
[_tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationRight];
}
}
I want to display images in a tableView from SQLite. Here is my retrieve image code from SQLite code. How do I load the images in the tableview?
-(void) retrieveData{
sqlite3 * database;
NSMutableArray *prodnamemutable = [[NSMutableArray alloc] init];
NSMutableArray *prodpricemutable = [[NSMutableArray alloc] init];
NSMutableArray *prodimagemutable = [[NSMutableArray alloc] init];
NSString *databasename=#"contacts.sqlite"; // Your database Name.
NSArray * documentpath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSAllDomainsMask, YES);
NSString * DocDir=[documentpath objectAtIndex:0];
NSString * databasepath=[DocDir stringByAppendingPathComponent:databasename];
if(sqlite3_open([databasepath UTF8String], &database) == SQLITE_OK)
{
const char *sqlStatement = "SELECT * FROM contacts"; // Your Tablename
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
[prodnamemutable removeAllObjects];
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
[prodnamemutable addObject:[NSString stringWithFormat:#"%s",(char *) sqlite3_column_text(compiledStatement, 1)]];
[prodpricemutable addObject:[NSString stringWithFormat:#"%s",(char *) sqlite3_column_text(compiledStatement, 3)]];
int length = sqlite3_column_bytes(compiledStatement, 0);
NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(compiledStatement, 0) length:length];
[prodimagemutable addObject:imageData];
NSLog(#"Length from db : %lu", (unsigned long)[imageData length]);
imageArray = [NSArray arrayWithArray:prodimagemutable];
NSLog(#"image found.%#",imageArray);
}
}
nameArray = [[NSArray alloc]initWithArray:prodnamemutable];
priceArray = [[NSArray alloc]initWithArray:prodpricemutable];
NSLog(#"nameArray:%#",nameArray);
[[self navigationController] tabBarItem].badgeValue = [NSString stringWithFormat:#"%lu",(unsigned long)[nameArray count]];
sqlite3_finalize(compiledStatement);
[self.tableView reloadData];
}
sqlite3_close(database);
}
UIImage *image = [UIImage imageWithData:data];
This will convert your image NSData to UIImage now this image can be shown on any UIImageView.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1; //count of section
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [prodimagemutable count]; //count number of row from image array.
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
cell.imageView.image = [UIImage imageWithData:[prodimagemutable objectAtIndex: indexpath.row]] ;
return cell;
}
//Below use for set height of cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 80;// or the height you want.
}
it will be better if you separated the code into multiple classes like the following
1. DBManager
#interface DBManager : NSObject
- (NSArray *)getImages;
#end
#implementation DBManager
- (NSArray *)getImages {
// put your code to retrieve the images from the database
// use the following to convert from NSData to UIImage
UIImage *image = [UIImage imageWithData:imageData];
}
#end
2. ImagesTableViewController
#interface ImagesTableViewController : UITableViewController
#property(nonatomic,strong) NSArray* images;
#end
#implementation ImagesTableViewController
- (void)viewDidLoad {
self.images = [dbManager getImages];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.images.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myCell"];
}
cell.imageView.image = self.images[indexpath.row];
return cell;
}
#end
Hi I have a TableView that is populated by an sqlite database, I've set up a UISearchBar to filter it but it returns no results. Here is my code for the search bar:
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = true;
entriesFiltered = [[NSMutableArray alloc] init];
NSString *queryPart1 = #"SELECT * FROM table WHERE name LIKE '%";
NSString *queryPart2 = #"'% ORDER BY name";
NSString *sql = [NSString stringWithFormat:#"%#%#%#", queryPart1, text, queryPart2];
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil)==SQLITE_OK)
{
while (sqlite3_step(statement)==SQLITE_ROW) {
char *field2 = (char *) sqlite3_column_text(statement,1);
NSString *field2Str = [[NSString alloc]initWithUTF8String:field2];
NSString *str = [[NSString alloc]initWithFormat:#"%#", field2Str];
[entriesFiltered addObject:str ];
}
sqlite3_finalize(statement);
}
}
[self.theTable reloadData];
}
Here is the code for the table view
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
//return the number of sections.
return 1;
}
-(NSInteger)tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section
{
//Return the number of rows in the section
if(isFiltered){
return [entriesFiltered count];
} else {
return [entries count];
}
}
- (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];
//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//Congigure the cell...
if(isFiltered){
cell.textLabel.text = [entriesFiltered objectAtIndex:indexPath.row];
return cell;
} else {
cell.textLabel.text = [entries objectAtIndex:indexPath.row];
return cell;
}
}
#pragma mark - Table view delegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = [self.theTable indexPathForSelectedRow];
NSLog(#" indexPath row %ld",(long)indexPath.row);
speakerViewController *svc = [segue destinationViewController];
svc.labelText = descriptions[indexPath.row];
svc.url = urls[indexPath.row];
}
Is the problem the sql query for searching? Would it be better to just search the array instead of querying the database? if so how would i do this?
Any help would be much appreciated.
I have image URL strings in database. Then I retrieving the images and add to productimg_array. I need to show the productimg_array images to UITableView cell. I'm using imageView.image=[UIImage imageNamed:[productimg_array objectAtIndex:indexPath.row]];
But app crashing.
const char *sql = "SELECT id,cat_id,product_image,order_by,description FROM product";
NSLog(#"sql is %s",sql);
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
// We "step" through the results - once for each row.
while (sqlite3_step(statement) == SQLITE_ROW) {
product_image = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 2)];
// NSLog(#"product_image is %#",product_image);
[productimg_array addObject:product_image];
}
}
TableView:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"productimg_array is %lu",(unsigned long)[productimg_array count]);
return [productimg_array 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];
}
for(int i=0; i<[productimg_array count];i++){
[cell.imageView setImageWithURL:[NSURL URLWithString:[productimg_array objectAtIndex:i]]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
cell.imageView.image = [productimg_array objectAtIndex:indexPath.row];
here cell.imageView.image expect an image in the position but the array has a set of strings that you are passing to set in the imageview
cell.imageView.image =[UIImage imageNamed:[productimg_array objectAtIndex:indexPath.row]];
Note :
product_image = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
can crash if the product_image is empty or null in db,so do this
char *nameChars = (char *) sqlite3_column_text(statement, 2);
if (nameChars) {
product_image = [[NSString alloc] initWithUTF8String:nameChars];
}
First you need to download that images from URL location and then you have to assign it to your image view.For this you can use lazy loading.
So Whenever I launch my app it looks like this and the first 3 cells are all the same. But once I start scrolling up and down it fixes and cell 2 and 3 show the correct information.
This is currently how my code looks like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"MyFeedCell";
SampleTableCell *cell = (SampleTableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"SampleTableCell" owner:self options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[UITableViewCell class]]) {
cell = (SampleTableCell *)currentObject;
break;
}
}
}
// Configure the cell.
NSUInteger row = [indexPath row];
NSUInteger count = [_allEntries count];
RSSEntry *entry = [_allEntries objectAtIndex:(count-row-1)];
NSString *imageString = entry.image;
imageString = [imageString stringByReplacingOccurrencesOfString:#"128x67" withString:#"768x432"];
NSLog(#"IMAGE : %#", imageString);
NSURL *imgURL = [[NSURL alloc] initWithString:imageString];
[cell.profilePicture setImageWithURL:imgURL placeholderImage:[UIImage imageNamed:nil]];
NSString *date = [entry.articleDate substringToIndex:12];
cell.datePosted.text = date;
cell.name.text = entry.articleTitle;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Here's a gif of how it's currently functioning
http://gyazo.com/2011099496257445c008a717beabd8fd
The whole topLevelObjects gambit is no longer necessary, replace your code with this and see if your still getting the problem:
//this above #interface
static NSString *CellIdentifier = #"MyFeedCell";
//Put this in viewDidLoad
[self.table registerClass:[SampleTableCell class] forCellReuseIdentifier:CellIdentifier];
[self.table registerNib:[UINib nibWithNibName:#"SampleTableCell" bundle:nil] forCellReuseIdentifier:CellIdentifier]
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
SampleTableCell *cell = (SampleTableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell.
NSUInteger row = [indexPath row];
NSUInteger count = [_allEntries count];
RSSEntry *entry = [_allEntries objectAtIndex:(count-row-1)];
NSString *imageString = entry.image;
imageString = [imageString stringByReplacingOccurrencesOfString:#"128x67" withString:#"768x432"];
NSLog(#"IMAGE : %#", imageString);
NSURL *imgURL = [[NSURL alloc] initWithString:imageString];
[cell.profilePicture setImageWithURL:imgURL placeholderImage:[UIImage imageNamed:nil]];
NSString *date = [entry.articleDate substringToIndex:12];
cell.datePosted.text = date;
cell.name.text = entry.articleTitle;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}