This is my View Controller, as you can see, there is a UITableView in the lower part.
I put the delegate and datasource in the .h file
#interface CourseFindrViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
While my .m file is this:
#interface CourseFindrViewController ()
{ sqlite3 *_db;}
#property (nonatomic, weak) IBOutlet UILabel *jNameLabel;
#property (weak, nonatomic) IBOutlet UITextView *jDescLabel;
#property (nonatomic, weak) IBOutlet UILabel *jEarningsLabel;
#property (weak, nonatomic) IBOutlet UITableView *cTableLabel;
#end
#implementation CourseFindrViewController
#synthesize jDetails =_jDetails;
-(void)viewWillAppear:(BOOL)animated {
_jDetails = (Jobs *)self.jDetails;
[self.jNameLabel setText:_jDetails.jName];
[self.jDescLabel setText:_jDetails.jDesc];
[self.jEarningsLabel setText:_jDetails.jEarnings];
NSLog(#"%d", _jDetails.jID);
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.jNameLabel = nil;
self.jDescLabel = nil;
self.jEarningsLabel = nil;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSArray *)course;
{
NSString *sqLiteDb = [[NSBundle mainBundle]pathForResource:#"CourseFindr" ofType:#"sqlite"];
sqlite3_stmt *statement;
NSMutableArray *retrieve = [[NSMutableArray alloc] init];
if (sqlite3_open([sqLiteDb UTF8String], &_db) != SQLITE_OK)
{
NSString *query= [NSString stringWithFormat:#"SELECT course. * FROM course INNER JOIN jobsCourse ON jobsCourse.courseID = course.cID WHERE jobsCourse.jobID = %d", _jDetails.jID];
if (sqlite3_prepare_v2(_db, [query UTF8String], -1, &statement, nil) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
int _cID = sqlite3_column_int(statement, 0);
char *cNameChars = (char *) sqlite3_column_text(statement,1);
char *cDescChars = (char *) sqlite3_column_text(statement, 2);
char *cSchoolChars = (char *) sqlite3_column_text (statement, 3);
char *cProgramChars = (char *) sqlite3_column_text(statement, 4);
NSString *_cName =cNameChars?[[NSString alloc]initWithUTF8String:cNameChars]:#"";
NSString *_cDesc = cDescChars?[[NSString alloc]initWithUTF8String:cDescChars]:#"";
NSString *_cSchool = cSchoolChars?[[NSString alloc]initWithUTF8String:cSchoolChars]:#"";
NSString *_cProgram = cProgramChars?[[NSString alloc]initWithUTF8String:cProgramChars]:#"";
Course *courses = [[Course alloc]
initWithCID:_cID
cName:_cName
cDesc:_cDesc
cSchool:_cSchool
cProgram:_cProgram];
[retrieve addObject:courses];
}
sqlite3_finalize(statement);
}
}
return retrieve;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *title1 = _jDetails.jName;
self.navigationItem.title = title1;
}
- (void)dealloc {
}
The code stops here. I added a breakpoint.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.course count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"courseCell"];
NSLog(#"Here.");
Course *courses = [self.course objectAtIndex:indexPath.row];
cell.textLabel.text =courses.cName;
cell.detailTextLabel.text =courses.cSchool;
return cell;
}
And it's still not passing the data to the table.. the table isn't appearing.
You have to add connection between table view and your datasource and delegate.
To do that simple control drag from your table view to view controller and select datasource and do the same but this time select delegate.
You must connect datasource and delegate in the xib. Plese let me know if this answer helped you.
Related
I am creating an iOS app. Since I am a beginner, I started with checking out some tutorials.
I started with creating an app with a Table View. The cells are dynamically filled through a database connection. This works fine.
However now I'm trying to define a push segue that opens a detail view for the cells. These also have to become filled dynamically with data. To achieve this, I started going through this tutorial and got it working up to "Passing Data Using Segue". In that step, you have to assign an identifier to your segue and fill in the prepareForSegue:sender: method.
I believe the implementation of my method causes the above error, because it isn't doing what it's supposed to. Looking up the error did not provide me with (understandable) answers since I fail to see how this problem has arisen.
Could someone please take a look at my code? Thanks in advance.
Main.storyboard:
In case you might be wondering, I did add an identifier to my segue, named showEventDetails.
EventsTableViewController.h
#import <UIKit/UIKit.h>
#import <sqlite3.h>
#interface EventsTableViewController : UITableViewController {
NSMutableArray *EventsArray;
sqlite3 *db;
}
#property (nonatomic, retain) NSMutableArray *EventsArray;
#property (nonatomic, strong) IBOutlet UITableView *eventTable;
-(NSMutableArray *) EventList;
#end
EventsTableViewController.m
#import "EventsTableViewController.h"
#import "TableCellViewController.h"
#import "Event.h"
#import <sqlite3.h>
#implementation EventsTableViewController
#synthesize EventsArray;
#synthesize eventTable;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[self EventList];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (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.
return [self.EventsArray count];
}
- (NSMutableArray *) EventList
{
EventsArray = [[NSMutableArray alloc] initWithCapacity:10];
#try {
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath]stringByAppendingPathComponent:#"eventsDb.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success) {
NSLog(#"Cannot locate database file '%#'.", dbPath);
}
if (!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK)) {
NSLog(#"An error has occured: %s", sqlite3_errmsg(db));
}
const char *sql = "SELECT * FROM events";
sqlite3_stmt *sqlStatement;
if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
NSLog(#"Problem with prepare statement: %s", sqlite3_errmsg(db));
}
else {
while (sqlite3_step(sqlStatement) == SQLITE_ROW) {
Event *event = [[Event alloc] init];
event.name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 1)];
event.date = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 2)];
event.starttime = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 3)];
event.endtime = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 4)];
event.location = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 5)];
event.description = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 6)];
event.favourite = sqlite3_column_int(sqlStatement, 7);
[EventsArray addObject:event];
event = nil;
}
}
sqlite3_finalize(sqlStatement);
}
#catch (NSException *exception) {
NSLog(#"Problem with prepare statement: %s", sqlite3_errmsg(db));
}
#finally {
sqlite3_close(db);
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EventCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
int rowCount = indexPath.row;
Event *event = [self.EventsArray objectAtIndex:rowCount];
cell.textLabel.text = event.name;
cell.detailTextLabel.text= event.description;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showEventDetails"]) {
NSIndexPath *indexPath = [self.eventTable indexPathForSelectedRow];
TableCellViewController *destViewController = segue.destinationViewController;
destViewController.eventName = [EventsArray objectAtIndex:indexPath.row];
}
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
#end
TableCellViewController.h
#import <UIKit/UIKit.h>
#interface TableCellViewController : UIViewController
#property(nonatomic, copy) NSString *eventName;
#property(nonatomic, strong) IBOutlet UILabel * eventNameLabel;
#property(nonatomic, copy) NSString *eventDate;
#property(nonatomic, strong) IBOutlet UILabel * eventDateLabel;
#property(nonatomic, copy) NSString *eventStarttime;
#property(nonatomic, strong) IBOutlet UILabel * eventStarttimeLabel;
#property(nonatomic, copy) NSString *eventEndtime;
#property(nonatomic, strong) IBOutlet UILabel * eventEndtimeLabel;
#property(nonatomic, copy) NSString *eventLocation;
#property(nonatomic, strong) IBOutlet UILabel * eventLocationLabel;
#property(nonatomic, copy) NSString *eventDescription;
#property(nonatomic, strong) IBOutlet UILabel * eventDescriptionLabel;
#property(nonatomic, assign) NSInteger eventFavourite;
#property(nonatomic, strong) IBOutlet UILabel * eventFavouriteLabel;
#end
TableCellViewController.m
#import "TableCellViewController.h"
#interface TableCellViewController ()
#end
#implementation TableCellViewController
#synthesize eventName;
#synthesize eventNameLabel;
#synthesize eventDate;
#synthesize eventDateLabel;
#synthesize eventStarttime;
#synthesize eventStarttimeLabel;
#synthesize eventEndtime;
#synthesize eventEndtimeLabel;
#synthesize eventLocation;
#synthesize eventLocationLabel;
#synthesize eventDescription;
#synthesize eventDescriptionLabel;
#synthesize eventFavourite;
#synthesize eventFavouriteLabel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the eventNameLabel with the name of the event
eventNameLabel.text = eventName;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before 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
Thanks again!
This is the offending line:
destViewController.eventName = [EventsArray objectAtIndex:indexPath.row];
You're trying to assign an object of type Event stored in the array, to an object of type NSString.
Since your string is defined with the copy modifier, the assignment tries to copy to object on the right side of the assignment (Event) but apparently this object doesn't conform to the NSCopying protocol, hence the error unrecognized selector... copyWithZone....
I have a UITableview that I have populated with data from a database, I know what to send data to another view (the detailViewController), however I can't get it to work, right now I am sending data via the - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { method. I have two classes the UITableview class and the detail class they are below. I also have an NSObject class that holds the objects for the database. Please check it out, here's my code:
UITableView Class code.:
Header File
#import <UIKit/UIKit.h>
#import <sqlite3.h>
#interface ExerciseViewController : UITableViewController {
NSMutableArray *theauthors;
sqlite3 * db;
}
#property(nonatomic,retain) NSMutableArray *theauthors;
-(NSMutableArray *) authorList;
#end
Implementation File
#import "ExerciseViewController.h"
#import "sqlColumns.h"
#import <sqlite3.h>
#import "UIColor+FlatUI.h"
#import "ExerciseDetailViewController.h"
#interface ExerciseViewController ()
#end
#implementation ExerciseViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Abdominal";
[self authorList];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.theauthors count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"exerciseCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
sqlColumns *author = [self.theauthors objectAtIndex:indexPath.row];
UILabel *exerciseName = (UILabel *)[cell viewWithTag:101];
exerciseName.text = author.Name;
UILabel *equipment = (UILabel *)[cell viewWithTag:102];
equipment.text = author.Equipment;
NSString *string = author.Equipment;
NSString *trimmedString = [string stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
if ([trimmedString isEqualToString:#"null"]) {
equipment.text = #"No Equipment";
}
UILabel *difficulty = (UILabel *)[cell viewWithTag:103];
difficulty.text = author.Difficulty;
if ([difficulty.text isEqualToString:#"Easy"]) {
difficulty.textColor = [UIColor emerlandColor];
}
if ([difficulty.text isEqualToString:#"Intermediate"]) {
difficulty.textColor = [UIColor belizeHoleColor];
}
if ([difficulty.text isEqualToString:#"Hard"]) {
difficulty.textColor = [UIColor alizarinColor];
}
if ([difficulty.text isEqualToString:#"Very Hard"]) {
difficulty.textColor = [UIColor alizarinColor];
}
UIImageView *cellImageView = (UIImageView *)[cell viewWithTag:100];
cellImageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#",author.File]];
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor cloudsColor];
bgColorView.layer.masksToBounds = YES;
[cell setSelectedBackgroundView:bgColorView];
return cell;
}
-(NSMutableArray *) authorList{
_theauthors = [[NSMutableArray alloc] initWithCapacity:10];
#try {
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"StayhealthyExercises.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success)
{
NSLog(#"Cannot locate database file '%#'.", dbPath);
}
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
{
NSLog(#"An error has occured: %s", sqlite3_errmsg(db));
}
const char *query = "SELECT * FROM strengthexercises WHERE primarymuscle LIKE '%abdominal%'";
const char *sql = query;
sqlite3_stmt *sqlStatement;
if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(#"Problem with prepare statement: %s", sqlite3_errmsg(db));
}else{
while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
sqlColumns * author = [[sqlColumns alloc] init];
author.Name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,1)];
author.Muscle = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
author.Description = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 3)];
author.File= [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 4)];
author.Sets= [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 5)];
author.Reps= [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 6)];
author.Equipment= [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 7)];
author.PrimaryMuscle= [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 8)];
author.SecondaryMuscle= [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 9)];
author.Difficulty= [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 10)];
[_theauthors addObject:author];
}
}
sqlite3_finalize(sqlStatement);
}
#catch (NSException *exception) {
NSLog(#"Problem with prepare statement: %s", sqlite3_errmsg(db));
}
#finally {
sqlite3_close(db);
return _theauthors;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"detail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
sqlColumns *author = [self.theauthors objectAtIndex:indexPath.row];
ExerciseDetailViewController *destViewController = segue.destinationViewController;
destViewController.exerciseImage.image = [UIImage imageNamed:author.File];
destViewController.descriptionLabel.text = author.Description;
}
}
#end
Now the DetailViewController
Header file:
#import <UIKit/UIKit.h>
#import "sqlColumns.h"
#interface ExerciseDetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIImageView *exerciseImage;
#property (weak, nonatomic) IBOutlet UILabel *descriptionLabel;
#property (nonatomic, strong) sqlColumns *author;
#end
Implementation File
#import "ExerciseDetailViewController.h"
#import "ExerciseViewController.h"
#interface ExerciseDetailViewController ()
#end
#implementation ExerciseDetailViewController
#synthesize exerciseImage,descriptionLabel,author;
- (void)viewDidLoad
{
[super viewDidLoad];
descriptionLabel.text = author.Description;
NSLog(#"%#",author.Description);
}
#end
Must be a small error, any help would be greatly appreciated!
I think the problem is that your outlets are nil. You can only set the text and the image after the viewDidLoad get called.
Try to save your info in other properties and after viewDidLoad get called assign this info to your label and image view.
In your prepare for segue:
destViewController.image = [UIImage imageNamed:author.File];
destViewController.text = author.Description;
In your header add those properties:
#property (strong, nonatomic) UIImage *image;
#property (strong, nonatomic) NSString *text;
Then in your viewDidLoad:
exerciseImage.image = self.image;
descriptionLabel.text = self.text;
i'm korean my english so simple
very very sorry
please help me
my application example phone book.
two View and tab bar with sqlite3 DB
first view is table view cell list, there are name is linked DB
second view save and find and delete phone book list with SQL query.
i want secondview save data and change tab update data list.
i coded [viewDidAppear] reloadData method
close the application re-open apllication is updated.
but not updated change the tap T_T please help me.
FirstViewController.h
#import <UIKit/UIKit.h>
#import "sqlite3.h"
#interface FirstViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>
{
NSString *path;
NSString *dbName;
NSString *databasePath;
sqlite3 *contactDB;
}
#property (nonatomic) sqlite3 *contactDB_2;
#property (strong,nonatomic) IBOutlet UITableView *myTable;
#property (nonatomic,retain) NSMutableArray *quizs;
-(void)checkAndCreateDatabase;
-(void)readFromDatabase;
#end
FistViewController.m
#import "FirstViewController.h"
#import "person.h"
#implementation FirstViewController
#synthesize contactDB_2,myTable;
#synthesize quizs;
-(void)checkAndCreateDatabase{
NSFileManager *filemgr = [NSFileManager defaultManager];
if([filemgr fileExistsAtPath:databasePath] == NO){
const char *dbPath = [databasePath UTF8String];
if(sqlite3_open(dbPath,&contactDB) == SQLITE_OK){
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS(ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT,ADRESS TEXT, PHONE TEXT)";
sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &errMsg);
sqlite3_close(contactDB);
}
}
}
-(void)readFromDatabase
{
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if(sqlite3_open(dbpath, &contactDB)==SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat:#"SELECT name,phone FROM contacts"];
const char *query_stmt = [querySQL UTF8String];
if(sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL)==SQLITE_OK)
{
while(sqlite3_step(statement)==SQLITE_ROW){
NSString* nameField = [[NSString alloc]initWithUTF8String:(const char*)sqlite3_column_text(statement, 0)];
NSString* phoneField = [[NSString alloc]initWithUTF8String:(const char*)sqlite3_column_text(statement, 1)];
person *persons = [person alloc];
[persons setName:nameField];
[persons setPhone:phoneField];
[quizs addObject:persons];
}
sqlite3_finalize(statement);
[myTable reloadData];
}
sqlite3_close(contactDB);
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"전화번호목록", #"전화번호목록");
self.tabBarItem.image = [UIImage imageNamed:#"first"];
}
return self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
pragma mark - View lifecycle
- (void)viewDidLoad
{
dbName = #"contacts2.db";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:dbName];
[self checkAndCreateDatabase];
quizs = [[NSMutableArray alloc] initWithCapacity:100];
[self readFromDatabase];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[myTable delegate];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[quizs removeAllObjects];
[self checkAndCreateDatabase];
[self readFromDatabase];
[myTable reloadData];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return quizs.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];
}
person *p = [quizs objectAtIndex:indexPath.row];
NSString *str = [[NSString alloc]initWithFormat:#"%# %#",p.name,p.phone];
cell.textLabel.text = str;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = indexPath.row;
NSString *temp = [[NSString alloc]initWithFormat:#"%d번쨰꺼 선택해뜸",row+1];
UIAlertView *alert =[[UIAlertView alloc] initWithTitle:#"터치" message:temp delegate:self cancelButtonTitle:nil otherButtonTitles:#"확인", nil];
[alert show];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#end
I want change the tab and update cell list.
Actually you can not insert the data in database in background .So until all data are inserted you have to keep application alive. If all data are saved successfully then please write reloadData code in ViewWillAppear.
I'm new to IOS and this is My first crud operation on it And I named this App As BIDDatabaseApp
Kindly be gentle with me i am just a learner i am getting difficulty to debug this problem.
I'm getting the error No visible #interface for BidProducts declares the selector nameProd and descProd which both are the properties at BidProducts , and the same error on NSArray with addObject
Now what i am doing is that i have make a database in Sqlite and use the storyboard with 3buttons for add view and delete.
OK, and this is my file hierarchy
BIDProducts.h
Sub-Class of NSObject
#import <Foundation/Foundation.h>
#interface BIDProducts : NSObject
#property (nonatomic, strong)NSString *nameProd;
#property (nonatomic, strong)NSString *descProd;
#end
BIDProducts.h
#import "BIDProducts.h"
#implementation BIDProducts
#synthesize nameProd,descProd;
#end
BIDViewController.h
here in BIDViewcontroller.h file i am importing the sqlite3.h it is xcode is not getting it by code i am writing it in a static way and it is not giving any error and it is not making a connection with the db also. I am still not able to connect with database.
#import <UIKit/UIKit.h>
#import "sqlite3.h"
#import "BIDProducts.h"
#interface BIDViewController : UIViewController<UITableViewDataSource , UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITextField *txtNameFeild;
#property (weak, nonatomic) IBOutlet UITextField *txtDescFeild;
#property (weak, nonatomic) IBOutlet UITableView *txtAreaViewList;
- (IBAction)btnAddProduct:(id)sender;
- (IBAction)btnDeleteProduct:(id)sender;
- (IBAction)btnViewProduct:(id)sender;
#end
BIDViewController.M
#import "BIDViewController.h"
#import "BIDProducts.h"
#interface BIDViewController ()
{
NSArray *arrayOFProducts;
sqlite3 *productsDB;
NSString *dbPathString;
}
#end
#implementation BIDViewController
- (void)viewDidLoad
{
[super viewDidLoad];
arrayOFProducts = [[NSMutableArray alloc]init];
[[self txtAreaViewList]setDelegate:self];
[[self txtAreaViewList]setDataSource:self];
[self createOrOpenDb];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)createOrOpenDb
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *docPath = [path objectAtIndex:0];
dbPathString = [docPath stringByAppendingPathComponent:#"productsDB.sqlite"];
char *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:dbPathString]) {
const char *dbPath = [dbPathString UTF8String];
if (sqlite3_open(dbPath, &productsDB) == SQLITE_OK) {
const char *sqlStmt = "CREATE TABLE IF NOT EXISTS TBLLISTPRODUCT (ID INTEGER PRIMERYKEY AUTOINCREMENT, PRODNAME VARCHAR, PRODDESC VARCHAR ) ";
sqlite3_exec(productsDB, sqlStmt, NULL, NULL, &error);
sqlite3_close(productsDB);
}
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrayOFProducts count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
BIDProducts *aProduct = [arrayOFProducts objectAtIndex:indexPath.row];
cell.textLabel.text = aProduct.nameProd;
cell.textLabel.text = aProduct.descProd;
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)btnAddProduct:(id)sender {
char *error;
if (sqlite3_open([dbPathString UTF8String], &productsDB) == SQLITE_OK) {
NSString *insertStmt = [NSString stringWithFormat:#"INSERT INTO TBLLISTPRODUCT(PRODNAME,PRODDESC) values ('%s', '%s') ", [self.txtNameFeild.text UTF8String] , [self.txtDescFeild.text UTF8String]];
const char *insert_stmt = [insertStmt UTF8String];
if (sqlite3_exec(productsDB, insert_stmt, NULL, NULL, &error) == SQLITE_OK) {
NSLog(#"person added");
BIDProducts *products = [[BIDProducts alloc]init];
[products nameProd:self.txtNameFeild.text];
[products descProd:self.txtDescFeild.text];
[arrayOFProducts addObject:products];
}
sqlite3_close(productsDB);
}
}
- (IBAction)btnDeleteProduct:(id)sender {
}
- (IBAction)btnViewProduct:(id)sender {
}
#end
Your syntax to set a property is wrong, it should be
products.nameProd = self.txtNameFeild.text;
which the compiler translates to the equivalent
[products setNameProd:self.txtNameFeild.text];
And arrayOFProducts should be declared as NSMutableArray
if you want to add objects to it.
(Note that you can remove the #synthesize statements from your source code,
the current Clang compiler synthesizes properties automatically.)
I have a view that is inserting information into the database. This view displays that information inside a table view (top half of view is being used for something else)
I have the view controller's class, an object class, and a table view cell class (this is what's throwing me off I think because the image and text labels are in here whereas the actual database information is in the view controller).
Here's the NSObject class:
// car.h
#import <Foundation/Foundation.h>
#interface Car : NSObject {
NSString *displayedMake;
NSString *displayedModel;
NSString *displayedImage;
}
#property (nonatomic, strong) NSString *displayedMake;
#property (nonatomic, strong) NSString *displayedModel;
#property (nonatomic, strong) NSString *displayedImage;
-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u;
#end
//car.m
#import "Car.h"
#implementation Car
#synthesize displayedMake, displayedModel, displayedImage;
-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u {
self.displayedMake = n;
self.displayedModel = d;
self.displayedImage = u;
return self;
}
#end
Here's the table view cell class:
//DisplayCarsCell.h
#import <UIKit/UIKit.h>
#interface DisplayCarsCell : UITableViewCell
#property (nonatomic, strong) IBOutlet UIImageView *carImage;
#property (nonatomic, strong) IBOutlet UILabel *makeLabel;
#property (nonatomic, strong) IBOutlet UILabel *modelLabel;
#end
//DisplayCarsCell.m
#import "DisplayCarsCell.h"
#import "ViewController.h"
#implementation DisplayCarsCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
And finally, the view controller:
//ViewController.h
#import <UIKit/UIKit.h>
#import "/usr/include/sqlite3.h"
#interface ViewController : UIViewController <UITableViewDelegate> {
//NSString *databasePath;
sqlite3 *carsDB;
NSArray *carImages;
NSMutableArray *cars;
}
#property (nonatomic, retain) NSMutableArray *cars;
#property (strong, nonatomic) IBOutlet UILabel *status;
#end
//ViewController.m
#import "ViewController.h"
#import "DisplayCarsCell.h"
#import "Car.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize cars;
-(NSString *) filePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[paths objectAtIndex:0] stringByAppendingPathComponent:#"cars.db"];
}
-(void) openDB {
if (sqlite3_open([[self filePath]UTF8String],&carsDB) != SQLITE_OK){
sqlite3_close(carsDB);
NSAssert(0, #"Database failed to open");
}
else{
NSLog(#"database opened");
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Opens the database and creates the table if its the first time
[self readCarsFromDatabase];
}
- (void)readCarsFromDatabase
{
// Setup the database object
//sqlite3 *database;
// Init the animals Array
cars = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
[self openDB];
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS apps (name text, id text, image text)";
if (sqlite3_exec(carsDB, sql_stmt, NULL, NULL, NULL) == SQLITE_OK)
{
NSLog(#"create db");
}
//Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "select * from apps";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(carsDB, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
//image, or first column in table
NSString *displayedImage=[NSString stringWithFormat: #"%s",(const char *)sqlite3_column_text(compiledStatement, 0)];
//name, or second column in table
NSString *displayedMake=[NSString stringWithFormat: #"%s",(const char *)sqlite3_column_text(compiledStatement, 1)];
//model, or third column in table
NSString *displayedModel=[NSString stringWithFormat: #"%s",(const char *)sqlite3_column_text(compiledStatement, 2)];
NSLog(#"%#, %#, %#",displayedImage, displayedMake, displayedModel);
_status.text = displayedMake;
NSLog(#"here");
// Create a new animal object with the data from the database
Car *carObject = [Car alloc];
carObject.displayedImage = [NSString stringWithFormat: #"%s",(const char *)sqlite3_column_text(compiledStatement, 0)];
// Add the animal object to the animals Array
[cars addObject:carObject];
//NSLog(#"%#",displayedImage);
}
}
else
{
printf( "could not prepare statement: %s\n", sqlite3_errmsg(carsDB) );
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
sqlite3_close(carsDB);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
#pragma mark Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return carImages.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"DisplayCarsCell";
DisplayCarsCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[DisplayCarsCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Configure the cell...
//UIImage *displayedImage = [UIImage imageNamed:
//[carImage objectAtIndex: [indexPath row]]];
// Car *carObj = [cars objectAtIndex:indexPath.row];
ViewController *viewController = (ViewController *)[[UIApplication sharedApplication] delegate];
Car *car = (Car *)[viewController.cars objectAtIndex:indexPath.row];
//[cell setImage:car.displayedImage];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// TODO: Select Item
NSLog(#"Selected");}
#end
The view controller itself is getting the array of data obviously from readCarsFromDatabase and is logging each row of the database correctly on viewDidLoad (did this to make sure that part wasn't wrong), but I need it to update the rows of the table view that is inside.
You have to call reloadData for your tableview once you're done adding records to cars, for example at the end of readCarsFromDatabase. I don't see an IBOutlet for the UITableView, but if it was simply tableView, then you'd add a line after sqlite3_close that says:
[self.tableView reloadData];
Obviously, make sure the table view's delegate is set to be your view controller.
Also, I would have thought that the following lines from your view controller's cellForRowAtIndexPath that currently say:
ViewController *viewController = (ViewController *)[[UIApplication sharedApplication] delegate];
Car *car = (Car *)[viewController.cars objectAtIndex:indexPath.row];
should be changed to simply say:
Car *car = self.cars[indexPath.row];