【发布时间】:2017-05-29 17:42:30
【问题描述】:
提前感谢您阅读本文并尝试帮助我解决问题。
我已经使用 sqlite 3 构建了一个数据库,我希望制作一个应用程序,我可以在其中输入产品信息(应该发送到数据库),然后在 UIViewTable 中查看。
然而,在创建了所有的类和方法之后——我的 UIViewTable 没有显示来自我的数据库的相关信息——它完全是空的?
我收到了一些反馈,说问题可能在于数据库连接不正确?
由于我的声誉很低,我只能附上 2 个链接,所以我试图展示我认为可以提供信息的最有用的屏幕截图。他们在这个问题的底部。
以下是我所有的相关文件;
sqlite3 数据库名为“StockControl.db”
//数据.h
#import <Foundation/Foundation.h>
@interface Data : NSObject
{
NSString *name;
NSNumber *price;
NSNumber *quantity;
}
@property (strong, nonatomic) NSString *name;
@property (nonatomic, strong) NSNumber *price;
@property (nonatomic, strong) NSNumber *quantity;
-(id)initWithData:(NSString*)n thePrice:(NSNumber*)p theQuantity:(NSNumber*)q;
@end
//数据.m
#import "Data.h"
@implementation Data
@synthesize name, price, quantity;
-(id)initWithData:(NSString*)n thePrice:(NSNumber*)p theQuantity:(NSNumber*)q{
if(self = [super init])
{
[self setName:n];
[self setPrice:p];
[self setQuantity:q];
}
return self;
}
@end
//SiteCell.h
#import <UIKit/UIKit.h>
@interface SiteCell : UITableViewCell
{
UILabel *primaryLabel;
UILabel *secondaryLabel;
UIImageView *myImageView;
}
@property (strong, nonatomic) UILabel *primaryLabel;
@property (strong, nonatomic) UILabel* secondaryLabel;
@property (strong, nonatomic) UIImageView *myImageView;
@end
//SiteCell.m
#import "SiteCell.h"
@implementation SiteCell
@synthesize primaryLabel, secondaryLabel, myImageView;
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self){
primaryLabel = [[UILabel alloc] init];
primaryLabel.textAlignment = NSTextAlignmentLeft;
primaryLabel.font = [UIFont systemFontOfSize:18];
primaryLabel.backgroundColor = [UIColor clearColor];
primaryLabel.textColor = [UIColor whiteColor];
secondaryLabel = [[UILabel alloc] init];
secondaryLabel.textAlignment = NSTextAlignmentLeft;
secondaryLabel.font = [UIFont systemFontOfSize:12];
secondaryLabel.backgroundColor = [UIColor clearColor];
secondaryLabel.textColor = [UIColor whiteColor];
myImageView = [[UIImageView alloc]init];
[self.contentView addSubview:myImageView];
[self.contentView addSubview:primaryLabel];
[self.contentView addSubview:secondaryLabel];
}
return self;
}
-(void)layoutSubviews{
[super layoutSubviews];
CGRect frame;
frame = CGRectMake(5, 5, 40, 40);
myImageView.frame = frame;
frame = CGRectMake(110, 5, 260, 20);
primaryLabel.frame = frame;
frame = CGRectMake(110, 30, 260, 20);
secondaryLabel.frame = frame;
}
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end
//StockPizza.h - UITableView 所在的 ViewController
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "SiteCell.h"
@interface StockPizza : UIViewController
<UITableViewDataSource, UITableViewDelegate>
{
AppDelegate *mainDelegate;
}
@property (strong, nonatomic) AppDelegate *mainDelegate;
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@end
//StockPizza.m - UIViewTable 所在的 ViewController
#import "StockPizza.h"
#import <UIKit/UIKit.h>
#import "Data.h"
#import "SiteCell.h"
@interface StockPizza ()
@end
@implementation StockPizza
@synthesize mainDelegate;
#pragma mark Table Methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [mainDelegate.stock count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 60;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellIdentifier = @"Cell";
SiteCell *cell = (SiteCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil){
cell = [[SiteCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
NSInteger row = indexPath.row;
Data *d = [mainDelegate.stock objectAtIndex:row];
cell.primaryLabel.text = d.name;
cell.secondaryLabel.text = [d.price stringValue];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSInteger row = indexPath.row;
Data *person = [mainDelegate.stock objectAtIndex:row];
NSString *title = person.name;
NSString *msg = [person.quantity stringValue];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"Ok" style:(UIAlertActionStyleDefault) handler:nil];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark View Methods
- (void)viewDidLoad {
[super viewDidLoad];
self.mainDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
UITabBar *tabBar = self.tabBarController.tabBar;
[tabBar setBarTintColor: [UIColor blackColor]];
[tabBar setTintColor: [UIColor whiteColor]];
// Do any additional setup after loading the view.
}
- (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
//AppDelegate.h
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
NSString *databaseName;
NSString *databasePath;
NSMutableArray *stock;
}
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) NSString *databaseName;
@property (strong, nonatomic) NSString *databasePath;
@property (strong, nonatomic) NSMutableArray *stock;
-(void)checkAndCreateDatabase;
-(void)readDataFromDatabase;
@end
//AppDelegate.m
#import "AppDelegate.h"
#import <sqlite3.h>
#import "Data.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
@synthesize databaseName, databasePath, stock;
#pragma mark Database Methods
-(void)checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:self.databasePath];
if (success)
return;
NSString *dataBasePathFromApp = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:self.databaseName];
[fileManager copyItemAtPath:dataBasePathFromApp toPath:self.databasePath error:nil];
}
-(void)readDataFromDatabase{
[self.stock removeAllObjects];
sqlite3 *database;
if (sqlite3_open([self.databasePath UTF8String], &database) == SQLITE_OK) {
char *sqlStatement = "select * from entries";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK){
while(sqlite3_step(compiledStatement) == SQLITE_ROW){
char *n = (char*)sqlite3_column_text(compiledStatement, 1);
float p = sqlite3_column_int(compiledStatement, 2);
int q = sqlite3_column_int(compiledStatement, 3);
NSString *name = [NSString stringWithUTF8String:n];
NSNumber *price = [NSNumber numberWithFloat:p];
NSNumber *quantity = [NSNumber numberWithInt:q];
Data *data = [[Data alloc] initWithData:name thePrice:price theQuantity:quantity];
[self.stock addObject:data];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
#pragma mark App Methods
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.stock = [[NSMutableArray alloc]init];
self.databaseName = @"StockControl.db";
NSArray * documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDir = [documentPaths objectAtIndex:0];
self.databasePath = [documentsDir stringByAppendingPathComponent: self.databaseName];
[self checkAndCreateDatabase];
[self readDataFromDatabase];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
截图
【问题讨论】:
-
您是否为 tableViewCell 创建了 xib ?如果是,请将该笔尖注册到视图控制器。
-
也许您应该尝试一些更高级别的数据库,例如 FMDB、Realm、CoreData、YapDatabase?
-
@MridulGupta 我还没有为 tableViewCell 制作 xib,实现一个可以提供解决方案吗?
标签: ios objective-c sqlite uitableview