2011-06-06 103 views
7

好吧,我知道这是一个模糊的概念性问题,但我真的需要帮助。如果您决定花时间阅读本文,请提前致谢。我甚至不会考虑写这么多,除非这是一个很棒的论坛,有很多有帮助的人,我认为这是最好的问题。如何将表视图“连接”到视图控制器

这是所有涉及到这方面的问题(你不必看它 - 我在下面解释一切):Pass parameter when initializing table

我已经工作了同样的问题日子,但我意识到必须有一些我很想念的东西。我已经使用google搜索,并且我甚至在几天前购买了两本Obj-C书籍(大约有50%读过),但我仍然认为它应该是非常容易的。我对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按钮,只需将NO参数推到级别2的其中一个,我就会是一个可怕但成功的程序员。

不幸的是,即使这样还没有解决。我已经尝试了在Interface Builder中可以想到的所有可能的控制拖动和窗口/视图/表组合,但无论我尝试什么,数据都不会加载到表视图中,即使它在我的第一个应用程序中运行良好。我已经经历了每一行代码 - 它们是相同的,除了某些东西需要“调用”或“启动”第2级的部分,我只是没有得到它。

所以,我打算在这里打破常规/期望,不要在我的问题中发布任何代码。我只想知道 - 这怎么可能如此困难?我的思维非常敏锐,我很快就接触到了,但是我必须说,我从来没有因为技术上的挑战而感到谦卑。

任何人都可以在概念层面向我解释我需要在这里做什么或者我失去了什么?即使你给我一个链接来阅读,我会非常感激。我在YouTube上观看了数十个小时的教程,但我总是注意更多。

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

感谢您用我痛苦的长信息承载。如果你做到了这一点,并对我有一些建议,我全部耳朵。尽管如此,我会诚实的 - 如果你告诉我,我应该放弃整个事情,并使用核心数据,我会哭。我真的不认为我有时间弄清楚管理数据的完全不同的方式。正如我所说,我对数据库和我的应用程序的查询部分非常满意 - 它只是管理这些令人烦恼的视图并在它们之间传递数据,这些数据让我非常痛苦!

任何帮助表示赞赏 - 非常感谢你。

+2

为什么downvote?这个问题完全合法,而不仅仅是另一个家庭作业问题。 – JustSid 2011-06-06 19:48:42

+0

@truthsmiles - 我很乐意向您解释这一点,随时在Google聊天中给我打电话。 (moshberm)与此同时,我会试着写一个答案。 – Moshe 2011-06-06 20:04:31

+2

@Moshe,如果我可以的话,告诉某人私下讨论会违背整个SO模型,因为它永远不会帮助其他任何人。 – Pops 2011-06-06 20:14:56

回答

4

如果我正确理解你的问题,你问如何初始化一个视图控制器,并通过一些数据来改变其行为。这里要理解的关键概念是在Objective-C中如何初始化对象。一个开发商谁是新到iOS拥有最常见的问题是:

HowcanIpassdatabetweenmyviews

是,八种不同的环节有。 (好吧,第八个链接有点偏离主题,但已经足够接近了。)有几种方法可以做到这一点,我会简单介绍一下。我还将介绍自定义初始化程序,这也是相关的一点。

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

  1. 您可以在“下一个”视图控制器上设置属性。 - 简单地说,我们可以创建一个UIViewController子类并设置productID属性(我们制作的)。让我们打电话给我们的新UIViewController a 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。 (函数被封装 - 也就是说,我们直接调用initalloc方法的结果)。

    然后,我们设置了我们视图的一个属性。该视图现在可以在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; 
    } 
    

    这个方法从NIB回报广大ProductPageViewController,但是,它不会加载我们的UI的初始化拷贝,又或如果这是一个UITableViewController,也不会设置UITableViewStyle。让我们先与NIB一起工作,然后展示如何工作UITableViewController。所以...

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

    现在。我们已经初始化了从NIB加载的ProductPageViewController,但它还没有做任何事情。请注意,我们没有公开NibNameBundle的论点,但我们只是将它们传递给自己。如果你愿意,你理论上也可以揭露这些。现在,让我们拿这个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; 
         } 
    

当让你的小节中,我建议持久性数据和定制初始化的组合。我还建议您看一下viewDidLoadviewWillAppear方法。

相关问题