2013-12-17 62 views
0

我是IOS開發人員中的一名相當新人,並且一直在與它鬥爭。我想顯示用戶在我的服務器上的電話列表,但tableview不顯示項目。我已經從服務器獲得了數據,我認爲UItableView的設置是正確的。這裏是我的代碼:無法重新加載IOS7中的表格視圖

STKPhoneHolderViewController.h

#import <UIKit/UIKit.h> 
#import "STKSimpleHttpClientDelegate.h" 

@interface STKPhoneHolderViewController : UITableViewController <UITableViewDataSource, STKSimpleHttpClientDelegate> 
@property (strong, nonatomic) IBOutlet UITableView *phoneTable; 
@property (strong, nonatomic) NSMutableArray *phoneArray; 

@end 

STKPhoneHolderViewController.m

@implementation STKPhoneHolderViewController 

- (id)initWithStyle:(UITableViewStyle)style 
{ 
    self = [super initWithStyle:style]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // Uncomment the following line to preserve selection between presentations. 
    // self.clearsSelectionOnViewWillAppear = NO; 

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 
    // self.navigationItem.rightBarButtonItem = self.editButtonItem; 

    self.phoneTable.dataSource = self; 
    self.phoneArray = [[NSMutableArray alloc]init]; 

    [self loadPhoneList]; 

} 


#pragma mark - Table view data source 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 

    // Return the number of rows in the section. 
    return [self.phoneArray count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"PhoneCell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
    } 

     STKPhoneHolder *phoneHolder = [self.phoneArray objectAtIndex:indexPath.row]; 
     [cell.textLabel setText:phoneHolder.userName]; 


    return cell; 
} 

#pragma Custom method 
- (void) loadPhoneList 
{ 

    self.phoneArray = [[NSMutableArray alloc]init]; 

    STKSimpleHttpClient *client = [[STKSimpleHttpClient alloc]init]; 
    client.delegate = self; 

    NSString *userId = @"your_id_h"; 

    NSString *sUrl = [NSString stringWithFormat:@"%@%@?userid=%@", 
         MOBILE_API_URL, 
         PHONEHOLDER_URI, 
         userId]; 

    [client send:sUrl data:@""]; 
} 

#pragma STKSimpleHttpClientDelegate 
-(void) complete:(STKHttpResult*) result 
{ 
    if (result.ok != YES){ 
     [STKUtility alert:result.message]; 
     return; 
    } 

    self.phoneArray = (NSMutableArray*)result.result; 
    for (STKPhoneHolder *holder in self.phoneArray) { 
     NSLog(@"%@", [holder description]); 
    } 

    [self.phoneTable reloadData]; 
    NSLog(@" isMainThread(%d)", [NSThread isMainThread]); 
} 


@end 

STKSimpleHttpClient.m

#import "STKSimpleHttpClient.h" 
#import "STKSimpleHttpClientDelegate.h" 

@implementation STKSimpleHttpClient 

NSMutableData *responseData; 
STKHttpResult *httpResult; 


void (^completeFunction)(STKHttpResult *); 

- (void) send:(NSString*)url 
     data:(NSString*)data 
{ 
    httpResult = [[STKHttpResult alloc]init]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 

     if (data == nil) return; 

     //Get request object and set properties 
     NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: url]]; 
     //set header for JSON request and response 
     [urlRequest setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
     [urlRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
     //set http method to POST 
     [urlRequest setHTTPMethod:@"POST"]; 
     //set time out 
     [urlRequest setTimeoutInterval:20]; 

     NSData *body = [data dataUsingEncoding:NSUTF8StringEncoding]; 
     //set request body 
     urlRequest.HTTPBody = body; 

     //connect to server 
     NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self]; 
     if (conn==nil){ 
      //Do something 
     } 
    }); 
} 

#pragma mark - NSURLConnection Delegate 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    // A response has been received, this is where we initialize the instance var you created 
    // so that we can append data to it in the didReceiveData method 
    // Furthermore, this method is called each time there is a redirect so reinitializing it 
    // also serves to clear it 
    responseData = [[NSMutableData alloc] init]; 

} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    // Append the new data to the instance variable you declared 
    [responseData appendData:data]; 
} 

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection 
        willCacheResponse:(NSCachedURLResponse*)cachedResponse { 
    // Return nil to indicate not necessary to store a cached response for this connection 
    return nil; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    // The request is complete and data has been received 
    // You can parse the stuff in your instance variable noow 
    NSError *error; 
    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; 

    BOOL ok = [[json objectForKey:@"ok"] boolValue]; 
    NSString *message = [json objectForKey:@"message"]; 
    if (ok == NO) { 
     [httpResult setError:message]; 
    } else { 
     [httpResult setSuccess:[json objectForKey:@"result"]]; 
    } 

    if (self.delegate !=nil) { 
     [self.delegate complete:httpResult]; 
    } 

    responseData = nil; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    // The request has failed for some reason! 
    // Check the error var 
    if (self.delegate !=nil) { 
     [self.delegate complete:[httpResult setError:@"Connection failed."]]; 
    } 
} 

STKPhoneHolder.m

#import <Foundation/Foundation.h> 

@interface STKPhoneHolder : NSObject 

@property NSString *deviceId; 
@property NSString *userId; 
@property NSString *userName; 
@property NSString *msn; 

- (id) initWithDeviceId:(NSString*)aDeviceId 
       userId:(NSString*)aUserId 
      userName:(NSString*)aUserName 
      msn:(NSString*)aMsn; 

@end 

登錄:

2013-12-17 16:14:23.447 [5323:70b] { 
    deviceId = 11111; 
    email = ""; 
    msn = 11111111; 
    role = ""; 
    userId = aaaaaa; 
    userName = "Joshua Pak"; 
} 
2013-12-17 16:14:23.448 [5323:70b] { 
    deviceId = 22222; 
    email = ""; 
    msn = 2222222; 
    role = ""; 
    userId = bbbbb; 
    userName = "Jasdf Pak"; 
} 
2013-12-17 16:14:23.449 Stalker[5323:70b] isMainThread(1) 

可以看我的日誌打印phoneArray與「完整」的方法,但實現代碼如下兩款手機只顯示「沒有記錄」。即使我調用reloadData方法,Tableview也不會再次渲染。我確保在調試模式下調用[self.phoneTable reloadData]。 我還需要做些什麼?

+0

@MaKo設置數據源,爲什麼設置委託? – Till

+4

您不需要創建表視圖的插座。一個表視圖控制器已經有一個tableView屬性(你在IB連接你的phoneTable插座?)。嘗試用self.tableView替換任何self.phoneTable引用 – rdelmar

+0

在numberOfRowsInSection中,放入一個NSLog並打印self.phoneArray計數。它是否顯示非零? – nhgrif

回答

-1

這是沒有必要指定部分的數量,但你可能想使用此代碼做到這一點:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; 
} 
+4

這不是必需的。默認是1. – rdelmar

+0

謝謝,不知道 – Hannes

+0

我是在故事板中做的,我還需要在源代碼中再做一次嗎?而且我無法顯示任何記錄而不是phoneArray,這意味着您提到的方法對我的問題沒有任何影響。最後,我添加了你的代碼,但它不起作用。不管怎樣,謝謝。 – sunghun

-1

我看你使用的是表視圖控制器,它已經具備了的tableView參考self.tableView

像@rdelmar說,你可以使用該引用,而不是你phoneTable:

[[self tableView] setDataSource:self]; 
[[self tableView] setDelegate:self]; 
[[self tableView] reloadData]; 
+1

代表不需要設置顯示數據。 –

+1

這是OP應該做的事情,但不會導致他的問題。他使用的方法是數據源方法,而不是委託方法。 – rdelmar

+0

redlmar你是對的。 @Guilherme,對不起,你的代碼不起作用。 – sunghun

3

試圖調用reloadData在主線程

#pragma STKSimpleHttpClientDelegate 
-(void) complete:(STKHttpResult*) result 
{ 
    if (result.ok != YES){ 
     [STKUtility alert:result.message]; 
     return; 
    } 

    self.phoneArray = (NSMutableArray*)result.result; 

    for (STKPhoneHolder *holder in self.phoneArray) { 
      NSLog(@"%@", [holder description]); 
     } 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.phoneTable reloadData]; 
    } 
} 

或者你可以使用performSelectorOnMainThread

[self.phoneTable performSelectorOnMainThread:@selector(reloadData) 
           withObject:nil 
           waitUntilDone:NO]; 

我猜STKSimpleHttpClient類調用complete委託func在不同的線程中,所有的用戶界面交互都假定從主線程調用。

試試這個代碼,看看你完整的委託功能

NSLog(@" isMainThread(%d)", [NSThread isMainThread]); 
+0

+1似乎是一個很好的猜測 - 應值得仔細檢查。 – Till

+0

我添加了STKSimpleHttpClient。對不起,你的代碼不起作用。我從STKSimpleHttpClient.m的send方法中刪除了dispatch_async,但仍然是相同的。 – sunghun

0

檢查這是哪個線程。代碼在從Web服務獲取信息之前加載tableview。如果是的話再編寫語句[tableview Reload];在Web服務信息獲取過程旁邊。這將有助於

相關問題