如何将表视图“连接”到视图控制器
好的,我知道这是一个模糊的概念性问题,但我真的需要帮助。 如果您决定花时间阅读本文,请提前致谢。 我甚至不会考虑写这么多,除非这是一个很棒的论坛,有很多有帮助的人,我认为这是最好的问题。
这一切都与这里的问题有关(你不必看它 - 我在下面解释一切):初始化表时传递参数
我一直在同一个问题上工作了几天,但我意识到必须有一些我很想念的东西。 我已经使用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这样的事情,我会通过电子邮件发送给你,如果你愿意看一看。 一旦我得到它的工作,我会在这里发布代码。 我必须相信还有其他人正在寻找和我一样的东西。 但更重要的是,我只想从高层知道解决我的问题的正确方法是什么? 如果你看看我的链接,你可以看到我一直在尝试的东西(这是将一个整数传递给填充表的方法),但正如我所说,我基本上放弃了,因为我没有到任何地方。 人们试图帮助我,但我是个白痴。
感谢我用令人难以置信的长信息承载。 如果你做到了这一点,并对我有一些建议,我全部耳朵。 尽管如此,我会诚实的 - 如果你告诉我,我应该放弃整个事情,并使用核心数据,我会哭。 我真的不认为我有时间弄清楚管理数据的完全不同的方式。 正如我所说,我对数据库和我的应用程序的查询部分非常满意 - 它只是管理这些令人烦恼的视图并在它们之间传递数据,这些数据让我非常痛苦!
任何帮助表示赞赏 - 非常感谢你。
如果我正确理解你的问题,你会问如何初始化一个视图控制器并传入一些数据来改变它的行为。 这里要理解的关键概念是在Objective-C中如何初始化对象。 iOS新手的开发人员最常遇到的问题之一是:
我如何在我的观点之间传递数据?
是的,那里有八个不同的链接。 (好吧,第八个链接有点偏离主题,但已经足够接近了。)有几种方法可以做到这一点,我会简单介绍一下。 我还将介绍自定义初始化程序,这也是相关的一点。
假设我们正在构建一个目录应用程序,其中显示了各种类别的一系列产品。 想象一下,我们的应用程序将打开一个产品列表,就像Apple Store应用程序一样。 说当用户点击一个产品时,我们想要显示一个产品页面。
您可以在“下一个”视图控制器上设置属性。 - 简单地说,我们可以创建一个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
配置视图,一切都很好。
您可以通过持久存储共享数据。 - 这种方法有点不同。 除了第一个呈现第二个视图控制器之外,视图控制器根本不进行通信。 只要第一个视图中的值发生更改(即,您想保留),就会将其写入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
}
您可以使用自定义初始化程序。 - 一旦理解了这个概念,这可能是最直观的方法,因为这是数据实际“通过”的唯一方式。 (与不直接共享数据的方法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加载,但它还没有做任何事情。 请注意,我们不公开NibName
和Bundle
参数,但我们只是将它们传递给自己。 如果你愿意,你理论上也可以揭露这些。 现在,让我们拿那个productID
并且做一些事情。
- (id) initWithProductID:(int)productID{
self = [super initWithNibName:@"ProductPageViewController" Bundle:nil];
if(self){
self.prodID = productID;
}
return self;
}
通过我们最新的变化,我们的“ PPVC
”现在知道productID
。 它可以根据需要查询数据库并对结果进行处理。 然后,您可以根据此产品productID
运行不同的查询。
另外两个快速提示:
也许你想传递几个论点。 当然,你可以简单地将它们添加到方法签名- (id) initWithProductID:(int)productID andCategoryID(int)categoryID
,但是如果你有五,六或五十六(是的,这是很多)参数会发生什么? 我建议传入一个集合或一组参数。
要在UITableView
使用自定义初始化程序,您需要传入UITableViewStyle
而不是NIB名称。 以下是它的样子:
- (id) initWithProductID:(int)productID{
self = [super initWithStyle:UITableViewStyleGrouped];
if(self){
self.prodID = productID;
}
return self;
}
在制作小节时,我建议组合持久数据和自定义初始化程序。 我还建议窥视viewDidLoad
和viewWillAppear
方法。
上一篇: How do I "connect" a table view to a view controller
下一篇: what does native="true" stand for in a Qt designer form