如何使用来自不同 ViewController 的 JSON 响应填充 UITableView?

Posted

技术标签:

【中文标题】如何使用来自不同 ViewController 的 JSON 响应填充 UITableView?【英文标题】:How to populate UITableView with the responce of JSON from a different ViewController? 【发布时间】:2012-01-23 09:01:25 【问题描述】:

我在 ***.com 中搜索和搜索,但无法摆脱这种情况,如何使用 GET 响应填充 TableView。我发送 GET 并在 DetailViewController(我的主控制器)中的一个方法中解析响应,并希望使用响应的一部分初始化 TableViewCell,并使用另一部分初始化该单元格的详细信息。我创建了 messageTableViewmessageDetailViewController ..如果问题不够清楚,我也可以共享代码。谢谢

编辑我知道这不是我们想要的,但我共享了所有代码,因为我无法在 viewControllers 之间绑定变量,我可以在视图之间导航,但我无法在彼此之间共享变量..

这是我的 DetailViewController 的界面文件(在我的应用中,它是主视图控制器)

#import <UIKit/UIKit.h>

@interface BNT_1DetailViewController : UIViewController <UISplitViewControllerDelegate>

    NSMutableArray *buttons;
    NSString *userName, *password, *serverIP;
    NSDictionary *mess;
    IBOutlet UITextField *userNameF;
    IBOutlet UITextField *passwordF;
    IBOutlet UITextField *serverF;
    NSURL *url;
    NSMutableArray *mesag;
    IBOutlet UIButton *acceptButton;
    NSMutableArray *mesID; //saving meesage ID s to NSMutableArray
    NSMutableArray *content; 


@property(retain,nonatomic)NSMutableArray *mesID,*content;
@property(assign,nonatomic)NSMutableArray *mesag ;
@property(retain, nonatomic)NSDictionary *mess;
//@property (retain,nonatomic)  NSMutableArray *buttons;
@property (retain, nonatomic) UITextField *userNameF;
@property (retain, nonatomic) UITextField *passwordF;
@property (retain, nonatomic) UITextField *serverF;
@property (retain, nonatomic) UIButton *acceptButton;
@property (retain, nonatomic) NSString *userName, *password, *serverIP;
@property (strong, nonatomic) id detailItem;
@property(retain,nonatomic)NSURL *url;
@property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;

-(IBAction)acceptAct:(id)sender;
-(IBAction)readMessages:(id)sender;
-(IBAction)secondAct:(id)sender;
@end

这是它的实现文件:

#import "BNT_1DetailViewController.h"
#import "mainMenu.h"
#import "messages.h"
@interface BNT_1DetailViewController ()
@property (strong, nonatomic) UIPopoverController *masterPopoverController;
- (void)configureView;
@end

@implementation BNT_1DetailViewController
@synthesize content,mesID,url;
@synthesize mesag,mess;
@synthesize userNameF, passwordF, serverF, acceptButton;
@synthesize userName, password, serverIP;
@synthesize detailItem = _detailItem;
@synthesize detailDescriptionLabel = _detailDescriptionLabel;
@synthesize masterPopoverController = _masterPopoverController;

-(IBAction)readMessages:(id)sender

    messages *message=[[messages alloc]initWithNibName:@"messages" bundle:nil];
    /*
     message.mesid=mesID;
     message.contents=content;
     */
    [self.navigationController pushViewController:message animated:TRUE];





-(IBAction)acceptAct:(id)sender


    userName=[[NSString alloc] initWithString:userNameF.text ];
    [userNameF setText:userName];
    NSUserDefaults *userNameDef= [NSUserDefaults standardUserDefaults];
    [userNameDef setObject:userName forKey:@"userNameKey"];
    password =[[NSString alloc] initWithString:passwordF.text];
    [passwordF setText:password];
    NSUserDefaults *passDef=[NSUserDefaults standardUserDefaults];
    [passDef setObject:password forKey:@"passwordKey"];
    serverIP=[[NSString alloc] initWithString: serverF.text];
    [serverF setText:serverIP];
    NSUserDefaults *serverDef=[NSUserDefaults standardUserDefaults];
    [serverDef setObject:serverIP forKey:@"serverIPKey"];
    [userNameDef synchronize];
    [serverDef synchronize];
    [passDef synchronize];


    UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"BNTPRO "
                                                      message:@"Your User Informations are going to be sent to server. Do you accept?"
                                                     delegate:self
                                            cancelButtonTitle:@"OK"
                                            otherButtonTitles:@"Cancel",  nil];
    [message show];


- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

    NSString *title = [alertView buttonTitleAtIndex:buttonIndex];

    if([title isEqualToString:@"OK"])
    
        if([userNameF.text isEqualToString:@""]|| [passwordF.text isEqualToString:@""] || [serverF.text length]<6) 
        
            UIAlertView *message1 = [[UIAlertView alloc] initWithTitle:@"BNTPRO "
                                                               message:@"Your User Informations are not defined properly!"
                                                              delegate:nil
                                                     cancelButtonTitle:@"OK"
                                                     otherButtonTitles:  nil];

            [message1 show];
            [userNameF  resignFirstResponder];
            [passwordF resignFirstResponder];
            return;
        
        mainMenu *ma=[[mainMenu alloc]initWithNibName:@"mainMenu" bundle:nil];
        NSString *str1=[@"?username=" stringByAppendingString:userNameF.text];
        NSString *str2=[@"&password=" stringByAppendingString:passwordF.text];
        NSString *str3=[str1 stringByAppendingString:str2];
        NSString *str4 =[@"http://" stringByAppendingString:serverF.text];


       url=[NSURL URLWithString:[str4 stringByAppendingString:[@"/ipad/login.php" stringByAppendingString:str3]]];
        //get the url to jsondata
        NSData *jSonData=[NSData dataWithContentsOfURL:url];

        if (jSonData!=nil) 
            NSError *error=nil;
            id result=[NSJSONSerialization JSONObjectWithData:jSonData options:
                       NSJSONReadingMutableContainers error:&error];
            NSLog(@"%@",result);       

            if (error==nil) 
            mess=[result objectForKey:@"message"];
                NSDictionary *messContent=[mess valueForKeyPath:@"message"];
                NSDictionary *messID=[mess valueForKeyPath:@"ID"];
                NSString*key1=[ result objectForKey:@"key" ];                
                NSString *s1=[@"http://" stringByAppendingString:serverF.text];
                NSString *s2=[s1 stringByAppendingString:@"/ipad/button.php"];
                NSURL *url2=[NSURL URLWithString:[s2 stringByAppendingString:[@"?key=" stringByAppendingString:key1]]];

                NSData *data2=[NSData dataWithContentsOfURL:url2];
                id result2=[NSJSONSerialization JSONObjectWithData:data2 options:NSJSONReadingMutableContainers error:nil];

                mesID = [NSMutableArray array];//saving meesage ID s to NSMutableArray
                content = [NSMutableArray array];    
                for ( mesag in mess) 

                    //i want to populate TableViewCells with the messID and the details of each cell(push in new view controller) will contain 'content' above

                  /*
                     [mesID addObject:[mesag objectForKey:@"ID"]];
                     [content addObject:[mesag objectForKey:@"message"]];    
                     */    
                    [[NSUserDefaults standardUserDefaults] setObject:messID forKey:@"message"];
                    [[NSUserDefaults standardUserDefaults] setObject:messContent forKey:@"messContent"];

                    // NSLog(@"%@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);
                    //   NSLog(@"The Message with ID %@ is: %@\n",messID,messContent);

                

                NSLog(@"MessID: %@",mesID);
                NSLog(@"Context: %@",content);


                buttons = [NSMutableArray array];
                CGFloat yPosition = 60.0f;
                CGFloat xPosition = 40.0f;

                const CGFloat buttonHeight = 75.0f;
                const CGFloat buttonMargin = 50.0f;
                UIButton *bt=[UIButton buttonWithType:UIButtonTypeRoundedRect];

                [bt setTitle:@"Messages" forState:UIControlStateNormal];
                [bt addTarget:self action:@selector(readMessages:) forControlEvents:UIControlEventTouchUpInside];
                bt.titleLabel.font=[UIFont systemFontOfSize:25];
                bt.frame=CGRectMake(300.0f, 700.0f,180.0f , 70.0f);
                [ma.view addSubview:bt];

                for(NSDictionary* buttonData in result2)  
                    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
                    NSString* buttonTitle = [buttonData objectForKey:@"name"];
                    NSString* buttonID=[buttonData objectForKey:@"ID"];
                    [button setTitle:buttonTitle forState:UIControlStateNormal];
                    [button setTag:[buttonID intValue]];
                    button.titleLabel.font=[UIFont systemFontOfSize:28];
                    button.frame = CGRectMake(xPosition, yPosition, 210.0f, buttonHeight);
                    [button addTarget:self action:@selector(secondAct:) forControlEvents:UIControlEventTouchUpInside];
                    [ma.view addSubview:button];
                    //   [v.buttons addObject:button];

                    xPosition = 260.0f;
                    yPosition+= buttonHeight + buttonMargin;

                


            [self.navigationController pushViewController:ma animated:TRUE];



         


-(IBAction)secondAct:(id)sender

    NSLog(@"ABC: %d",[sender tag]);



- (void)dealloc

    [_detailItem release];
    [_detailDescriptionLabel release];
    [_masterPopoverController release];
    [super dealloc];


#pragma mark - Managing the detail item

- (void)setDetailItem:(id)newDetailItem

    if (_detailItem != newDetailItem) 
        [_detailItem release]; 
        _detailItem = [newDetailItem retain]; 

        // Update the view.
        [self configureView];
    

    if (self.masterPopoverController != nil) 
        [self.masterPopoverController dismissPopoverAnimated:YES];
            


- (void)configureView

    // Update the user interface for the detail item.

    if (self.detailItem) 
        self.detailDescriptionLabel.text = [self.detailItem description];
    


- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.


#pragma mark - View lifecycle

- (void)viewDidLoad

    [super viewDidLoad];
    [passwordF setSecureTextEntry:YES];
    userNameF.font=[UIFont systemFontOfSize:24];

    userNameF.frame = CGRectMake(320.0f,60.0f,360.0f,50.0f);
    passwordF.frame = CGRectMake(320.0f,145.0f,360.0f,50.0f);
    serverF.frame= CGRectMake(320.0f,235.0f,360.0f,50.0f);
    userNameF.font=[UIFont boldSystemFontOfSize:24];
    [userNameF becomeFirstResponder];
    serverF.font=[UIFont boldSystemFontOfSize:24];
    passwordF.font=[UIFont systemFontOfSize:24];


    acceptButton.titleLabel.font=[UIFont boldSystemFontOfSize:26];
    // Do any additional setup after loading the view, typically from a nib.
    [self configureView];


- (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];


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

    // Return YES for supported orientations
    return YES;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
        self.title = NSLocalizedString(@"Detail", @"Detail");
    
    return self;


#pragma mark - Split view

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController

    barButtonItem.title = NSLocalizedString(@"Master", @"Master");
    [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
    self.masterPopoverController = popoverController;


- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem

    // Called when the view is shown again in the split view, invalidating the button and popover controller.
    [self.navigationItem setLeftBarButtonItem:nil animated:YES];
    self.masterPopoverController = nil;


@end

我想用 messID 填充 TableViewCells,每个单元格的详细信息(推入新视图控制器)将包含上面的“内容”

这是我的TableViewController 文件,名为messages: (.h 文件)

#import <UIKit/UIKit.h>

@interface messages : UITableViewController

    NSMutableArray *mesid,*contents; 



@property(retain,nonatomic)NSMutableArray *mesid,*contents;


@end

和.m文件:

#import "messages.h"
#import "messageDetail.h"
@implementation messages
@synthesize mesid;
- (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

    [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;


- (void)viewDidUnload

    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;


- (void)viewWillAppear:(BOOL)animated

    

- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];


- (void)viewWillDisappear:(BOOL)animated

    [super viewWillDisappear:animated];


- (void)viewDidDisappear:(BOOL)animated

    [super viewDidDisappear:animated];


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

    // Return YES for supported orientations
    return YES;


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

#warning Incomplete method implementation.
    // Return the number of rows in the section.

   return [mesid 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] autorelease];
    
    cell.textLabel.text=[mesid objectAtIndex:indexPath.row];
    [tableView reloadData]; 
    // Configure the cell...

    return cell;



// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

    // Return NO if you do not want the specified item to be editable.
    return YES;




// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

    if (editingStyle == UITableViewCellEditingStyleDelete) 
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
       
    else if (editingStyle == UITableViewCellEditingStyleInsert) 
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
       



/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath


*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath

    // Return NO if you do not want the item to be re-orderable.
    return YES;

*/

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    // Navigation logic may go here. Create and push another view controller.

     messageDetail *detailViewController = [[messageDetail alloc] initWithNibName:@"messageDetail" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     detailViewController.title=@"Message Detail";
     [detailViewController release];



@end

我的最后一个控制器是 messageDetails。它的接口文件是:

#import <UIKit/UIKit.h>

@interface messageDetail : UIViewController

@end

最后一个,messageDetail的实现文件:

#import "messageDetail.h"

@implementation messageDetail

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    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

    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.


- (void)viewDidUnload

    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

    // Return YES for supported orientations
    return YES;


@end

【问题讨论】:

我编辑了问题,希望这种风格不会太无聊:) 【参考方案1】:

我快速浏览一下就发现了几个问题: 1. 你有一个 UITableViewController 的实例。 UITableViewController 的正确初始化是initWithStyle: 改用它。否则你需要做一些额外的工作,而且真的不需要。 2. 您正在检查UIAlertView 实例中按钮的字符串。我的建议是不要这样做。字符串在某种程度上是易变的。可以将多语言作为一项功能插入,之后您可能会遇到问题。而是检查索引。这是一个简单的 int,而不是令人头疼的警报! 3. 您已将NSMutableArray 设置为messages 类中的属性。你为什么不填充它。这就是信息没有出现在您的表格中的原因:因为您没有将其提供给特定的班级。 从控制器初始化控制器(包含表视图的类),提供原始控制器的内容。

建议: 4. 为了标准化,用大写字母命名你的类,用小字母命名你的变量。常量应以“k”字母开头。

【讨论】:

谢谢大家,我是一个新手,我遇到了一些麻烦。你能帮我写代码吗?:) 特别是你第三个(3.)是我不知道的暂时弄清楚..你能把它写成代码吗。 例如,我不知道如何在 messageDetail 视图中显示消息(内容)的详细信息.. 请假设我刚刚问过这个问题:您好,在我的应用程序中,我向我的服务器发送了一个 GET 并收到了一些响应。我的主视图控制器类期望有 TavleView 和 TableViewController 类。我在我的主 ViewController 中进行解析,我想用我从第一个 ViewController 收到的结果填充 TableViewCells。而且我还想在一个名为 DetailViewController 的新 ViewController 中显示任何单元格的详细信息。现在,视图之间的任何导航都可以按照我的意愿工作

以上是关于如何使用来自不同 ViewController 的 JSON 响应填充 UITableView?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不同的 ViewController 中使用 JSONModel 数据?

如何通过来自同一个 TableViewController 的多个 segue 到同一个 ViewController

如何在一个 viewController 上使用多个搜索栏来访问 Swift 中的不同 JSON 数据?

Swift3,如何在不同的 viewController 中使用相同的 UITableView

如何根据 iOS 中的两个条件从 AppDelegate 呈现两个不同的 ViewController?

使用情节提要时如何在appDelegate中获取指向viewController的指针