2017-01-14 40 views
0

預先感謝您閱讀本文並嘗試幫助我解決問題。UITableView不顯示我的數據?

我已經使用sqlite 3來形成一個數據庫,我希望做一個應用程序,我可以輸入產品的信息(應該發送到數據庫),然後在UIViewTable中查看。

但是,在創建了所有類和方法之後 - 我的UIViewTable不顯示來自我的數據庫的相關信息 - 它完全是空的?

我有一些反饋,說這個問題可能在於數據庫沒有正確連接的事實?

由於我的聲望很低,我只能附加2個鏈接,所以我試圖展示我認爲會提供信息的最有用的截圖。他們在這個問題的底部。

以下是我所有的相關文件;

的sqlite3的數據庫被稱爲 「StockControl.db」

//Data.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 

//Data.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舉行

#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舉行

#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 

截圖

UIViewTable with Outlets || Storyboard overview

+0

您是否爲tableViewCell創建了xib?如果是,請將該筆尖註冊到視圖控制器。 –

+0

也許你應該嘗試一些更高級別的數據庫,如FMDB,Realm,CoreData,YapDatabase? – iWheelBuy

+0

@MridulGupta我還沒有爲tableViewCell製作xib,會實現一個提供解決方案嗎? – FarisZ

回答

0

謝謝你的努力!

原來,這是我自己的錯,因爲數據庫中的表被命名爲「股票」,我的sqlStatement試圖調用一個名爲條目的表。改變這個錯誤後,它顯示爲我想要的!

我對此表示歉意,但我很感謝您的洞察力。

0

我認爲Mridul是正確的,你只是錯過了一個插座,但有些事情你可以做,以幫助你自己的調試過程。

也許您已經確認您確實正在獲取您期望的數據 - 但您並未說明您已檢查過該數據。我認爲總是有值得一些調試檢查或打印語句,以確保您實際獲得您期望的數據。

另一件事,看起來你會爲每個tableview分開不同的類 - 你可以通過一個表現類來處理所有tableview開銷,並簡單地加載數據需要你的5個不同的來源。

在readDataFromDatabase()你有線
+0

謝謝羅素和Mridul。我完全沒有意識到我沒有爲UITableView做出一個出路。我現在用插座正確更新了代碼,但表格仍然是空的。我錯過了一個額外的步驟?我已將該outlet命名爲tableView。但是,我是否認爲.m文件可能需要修改才能修改我製作的插座?或者我已經在表格上調用了顯示信息的代碼? – FarisZ

+0

也謝謝你提供關於使用NSLogs進行測試的信息,我會在未來考慮這些,並且會試着養成它的習慣,因爲它看起來非常有幫助。 我對羅素編碼還是很新的,所以我不太確定演示類是什麼,但我也有一種感覺,我的多表實現並不理想。我將研究演示課程以嘗試和了解更多信息。再次感謝你:) – FarisZ

+0

羅素,我一直在試圖做打印報表來檢查這些東西是否正確。但我的調試區域不打印任何東西?我應該在哪裏做呢?我應該打印什麼來測試我的數據庫以確保它已正確加載:)? – FarisZ

0

浮子P = sqlite3_column_int(compiledStatement,2);

它應該讀取float p = sqlite3_column_float(compiledStatement,2);

+0

我嘗試使用'float = sqlite3_column_float(compiledStatement,2);'但sqlite3_column_float'不是C99根據xCode支持的代碼錯誤。當我輸入sqlite3_column_時,它不會顯示爲選項。 – FarisZ