【问题标题】:How do I "connect" a table view to a view controller如何将表视图“连接”到视图控制器
【发布时间】:2011-09-09 13:33:55
【问题描述】:

好的,我知道这是一个模糊的概念性问题,但我真的需要帮助。如果您决定花时间阅读本文,请提前致谢。我什至不会考虑写这么多,除非这是一个很棒的论坛,有这么多乐于助人的人,我认为这是最好的地方。

这都与这里的问题有关(你不必看 - 我在下面解释一切):Pass parameter when initializing table

我已经为同一个问题工作了好几天,但我意识到我一定缺少一些重要的东西。几天前,我用谷歌搜索和搜索,我什至买了(大约 50% 的人阅读了)两本 Obj-C 书籍,但我仍然在掌握一些看起来应该非常容易的东西。我显然对 OOP 很陌生,但我在 HTML、perl、sql、python 以及一些古老的东西(如 pascal 和 basic)方面的技能平庸。我是一个 n00b,但不是白痴(嗯,实际上这种经历让我改变了一些想法)。

无论如何,我的最终目标是在第一个视图(第 1 级)上创建一个带有 8 个“普通”按钮的应用程序,每个按钮基本上都做同样的事情 - 即显示一个简单的表格视图(第 2 级)单元格中的数据可以单击以继续深入了解详细信息(第 3 级)。非常基本和直接的概念。 8 个可能的 2 级之间的唯一区别是将显示的数据。我已经为每个按钮构建了可以按我想要的方式工作的 sql 查询。

所以,这就是我的立场:我有一个完美运行的应用程序,从 2 级开始,一切都完全符合我的预期 - 查询有效,表格很漂亮 - 这太棒了。

另外,我还有另一个基于导航的应用程序,它在“1 级”启动并显示 8 个按钮(我在 1 级隐藏了导航栏)。如果我单击 1 级上的任何按钮,则 2 级视图(即导航栏 + 表格)会完全按照我的意愿滑入视图。问题是表格只是空白。无论我做什么,我都无法在第二个应用程序中获得 2 级来向我显示数据,即使我可以在第一个应用程序中完美地显示所有这些数据。对于我的生活,我无法弄清楚如何将 1 级与 2 级“链接”。

希望您能理解我试图弥合的这个差距。由于 2 级有 8 种可能性(同一个 sql 表上的 sql 查询只有非常细微的差异),我最初尝试想出一种将整数“传递”到 2 级视图的方法(在第一个应用程序中)和然后根据传递的内容选择 sql 查询(有关该惨败,请参见上面的链接)。一旦我开始工作,我计划稍后弄清楚如何让按钮进行“传递”。然而,在搞砸了大约 16 个小时之后,我放弃了,决定制作 8 个不同的表视图控制器,除了查询之外,所有的代码几乎相同。那样的话,如果我可以在 1 级上获得一个 SINGLE 按钮来简单地按下没有参数的 2 级中的一个,那我将是一个糟糕但成功的程序员。

不幸的是,即使这样对我来说也没有奏效。我已经尝试了在 Interface Builder 中我能想到的所有可能的控制拖动和窗口/视图/表格组合,但无论我尝试什么,数据都不会加载到表格视图中,即使它在我的第一个应用程序中效果很好。我已经浏览了每一行代码 - 它们是相同的,除了必须“调用”或“启动”第 2 级部分,而我就是不明白。

因此,我将在这里打破惯例/期望,并且不在我的问题中发布任何代码。我只想知道——这怎么可能这么难??我具有很强的分析能力,而且我很快就赶上了,但我不得不说,我一生中从未因技术挑战而如此自卑。

谁能从概念上向我解释我需要在这里做什么或我缺少什么?即使你给我一个链接到要阅读的东西,我也会非常感激。我已经在 youtube 上观看了数十小时的教程,但我一直都在等待更多。

我当然愿意分享我的代码,但是代码太多了,而且我对此很陌生,我真的不知道相关部分在哪里。另外,我实际上想了解所有这些是如何工作的,以便我可以帮助他人。如果这里有 PM 这样的东西,如果你愿意看一下,我会通过电子邮件发送给你。一旦我得到它的工作,我会在这里发布代码。我必须相信还有其他人在寻找与我相同的东西。但是,更重要的是,我只想从高层次上知道,解决我的问题的正确方法是什么?如果您查看我的链接,您会看到我一直在尝试什么(将整数传递给填充表格的方法),但正如我所说,我基本上放弃了,因为我没有得到任何结果。人们试图帮助我,但我是个白痴。

感谢您接受我冗长的信息。如果你做到了这一步并对我有一些建议,我会全力以赴。不过,我会说实话 - 如果你告诉我我应该放弃整个事情并使用核心数据,我会哭的。我真的认为我没有时间想出一种完全不同的数据管理方式。正如我所说,我对我的应用程序的数据库和查询部分感到非常满意 - 它只是管理令人讨厌的视图并在它们之间传递数据,这让我很生气!

感谢任何帮助 - 非常感谢。

【问题讨论】:

  • 为什么投反对票?这个问题是完全合法的,而不仅仅是另一个家庭作业问题。
  • @truthsmiles - 我很乐意向您解释这一点,请随时在 Google 聊天中联系我。 (moshberm)与此同时,我将尝试写一个答案。
  • @Moshe,如果可以的话,-1,告诉某人私下讨论违背了整个 SO 模型,因为它永远不会帮助其他任何人。
  • @truth,我并没有对你投反对票,但是当你将网站称为“论坛”时,这里的一些人可能会......很棘手......那是因为 SO 开始解决论坛存在的许多问题。
  • @LordTorgamus - 大人,如果我的回答让您满意,您可以投票。 ;-)

标签: iphone uiviewcontroller uitableview parameter-passing


【解决方案1】:

如果我正确理解您的问题,您是在询问如何初始化视图控制器并传入一些数据以改变其行为。这里要理解的关键概念是如何在 Objective-C 中初始化对象。刚接触 iOS 的开发者最常遇到的问题之一是:

HowcanIpassdatabetweenmyviews?

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

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

  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。 (函数被包装了——也就是说,我们直接在alloc方法的结果上调用init。)

    然后,我们设置视图的属性。现在可以在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 方法。您可能还注意到UITableViewControllers 使用了不同的初始化程序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 加载,但它还没有做任何事情。请注意我们如何不公开 NibName 和 Bundle 参数,但我们只是将它们传递给自己。如果你愿意,理论上你也可以公开这些。现在,让我们用 productID 做点什么吧。

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

    随着我们最新的变化,我们的“PPVC”现在知道productID。它可以根据需要查询数据库并对结果进行处理。然后,您可以基于此productID 运行不同的查询。

另外两个快速提示:

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

在制作小节时,我建议结合使用持久数据和自定义初始化程序。我还建议查看viewDidLoad 和viewWillAppear 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多