如何将表视图“连接”到视图控制器

时间:2011-06-06 19:32:58

标签: iphone uiviewcontroller uitableview parameter-passing

1 个答案:

答案 0 :(得分:4)

如果我正确理解你的问题,你就会问如何初始化一个视图控制器并传入一些数据来改变它的行为。这里要理解的关键概念是如何在Objective-C中初始化对象。 iOS新手开发人员最常见的问题之一是:

  

How can I pass data between my views

是的,那里有八个不同的链接。 (好吧,第八个链接有点偏离主题,但它足够接近。)有几种方法可以做到这一点,我将简要介绍它们。我还将描述自定义初始值设定项,这也是一个相关点。

让我们假装我们正在构建一个目录应用程序,它显示了各种类别的产品。想象一下,我们的应用程序打开了一个产品列表,就像Apple Store App一样。假设当用户点击产品时我们想要显示产品页面。

  1. 您可以在“下一个”视图控制器上设置属性。 - 简单地说,我们可以创建一个UIViewController子类并设置productID属性(我们可以捏造)。我们打电话给新UIViewController一个ProductPageViewController。这是看起来的样子:

    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
    
      //Create a ProductPageViewController
      ProductPageViewController *ppvc = [[ProductPageViewController alloc] initWithNibName:@"ProductPageViewController" bundle:nil];
      //set the property on our ProductPageViewController
      [ppvc setProductID:42];
      //We would usually present the PPVC here.
      //After presenting, remember to release the view controller
    }
    

    在第一行中,我们创建了产品视图控制器。我们拨打alloc,然后拨打init。 (函数被包装 - 也就是说,我们直接在init方法的结果上调用alloc。)

    然后,我们设置了视图的属性。现在可以在viewWillAppear中配置视图,一切都很顺利。

  2. 您可以通过持久性商店共享数据。 - 此方法的工作方式略有不同。视图控制器根本不进行通信,除了第一个呈现第二个视图控制器。只要第一个视图中的值发生更改(您希望保留),就可以将其写入Core Data或NSUserDefaults。然后,新视图会根据需要读取值。

    在您的第一个视图控制器中:

    //A method to store the data
    - (void)storeData:(id)pageID{
        [[NSUserDefaults setObject:pageID forKey:@"pageID"];
    }
    
    - (void)showNewPPVC{
    
      ProductPageViewController *ppvc = [[ProductPageViewController alloc] initWithNibName:@"ProductPageViewController" bundle:nil];        
      //Show and then release the PPVC
    }
    
  3. 您可以使用自定义初始化程序。 - 一旦您理解了这个概念,这可能是最直观的方法,因为这是唯一一个实际“传递”数据的方法。 (与没有直接共享数据的方法2和将数据作为属性传递的方法1相反。)

    请注意,在前面的示例中,我使用了initWithNibName:Bundle方法。您可能还注意到UITableViewController使用了不同的初始化程序initWithStyle:。这两个初始化器为新对象接收一些信息,以便它知道如何加载。让我们先看看第一个:

    - (id)initWithNibName:(NSString *)nibNameOrNil Bundle:(NSBundle *)bundleNameOrNil;
    

    第一个参数告诉视图控制器加载哪个nib文件。我现在要忽略第二个论点,因为除了nil之外,我从未见过任何传递过的东西。向右移动到第二个例子:

    - (id)initWithStyle:(UITableViewStyle)style;
    

    您可以在此处传递两个UITableViewStyle值中的一个。这是定义表视图样式的一种方法(另一种方法是直接修改nib文件)。

    让我们将这个概念扩展到我们的例子。我现在要向您展示如何制作自己的自定义初始化程序。让我们初始化我们的ProductPageViewController实例:

    - (id) initWithProductID:(int)productID;
    

    这很简单。现在,我们需要实现该方法并实际使用产品ID执行某些操作。我们将从这里的准系统代码开始,需要“模仿”默认初始化程序的功能。

    - (id) initWithProductID:(int)productID{
     self = [super init];
    
     return self;
    }
    

    此方法将返回ProductPageViewController的初始化副本,但是,它还不会从NIB加载我们的UI,或者如果这是UITableViewController,则不会设置UITableViewStyle。让我们首先使用NIB,然后我将展示如何使用UITableViewController。所以...

    - (id) initWithProductID:(int)productID{
     self = [super initWithNibName:@"ProductPageViewController" Bundle:nil];
    
     return self;
    }
    

    现在。我们有一个初始化的ProductPageViewController,从NIB加载,但它还没有做任何事情。请注意我们如何不公开NibNameBundle参数,但我们只是将它们传递给自己。如果你愿意,你理论上也可以揭露它们。现在,我们来看看productID并用它做点什么。

    - (id) initWithProductID:(int)productID{
     self = [super initWithNibName:@"ProductPageViewController" Bundle:nil];
    
       if(self){
         self.prodID = productID;
       }
    
     return self;
    }
    

    根据我们的最新更改,我们的“PPVC”现在知道productID。它可以根据需要查询数据库并对结果执行操作。然后,您可以根据此productID运行不同的查询。

  4. 两个更快的提示:

    1. 也许你想传递几个参数。当然你可以简单地将它们添加到方法签名- (id) initWithProductID:(int)productID andCategoryID(int)categoryID中,但是如果你有五个,六个或五十六个(是的,很多)参数会发生什么呢?我建议传入一个集合或一组参数。

    2. 要将自定义初始值设定项与UITableView一起使用,请传入UITableViewStyle而不是NIB名称。这是它的样子:

            - (id) initWithProductID:(int)productID{
              self = [super initWithStyle:UITableViewStyleGrouped];
      
              if(self){
                self.prodID = productID;
              }
      
              return self;
            }
      
    3. 在制作小节时,我建议使用持久数据和自定义初始值设定项的组合。我还建议您查看viewDidLoadviewWillAppear方法。