代码之家  ›  专栏  ›  技术社区  ›  Adam Alexander

使用单独的委托/数据源时UITableView问题

  •  54
  • Adam Alexander  · 技术社区  · 16 年前

    一般说明:

    首先,我有一个 UITableView 已使用Interface Builder将其放置到Xcode生成的视图中。视图的文件所有者设置为Xcode生成的 UIViewController . 在这个子类中,我添加了 numberOfSectionsInTableView: tableView:numberOfRowsInSection: tableView:cellForRowAtIndexPath: 表视图的 dataSource delegate

    上述配置工作正常。当我想移动此表视图的 数据源 代表

    • 创建的新子类 UITableViewController 在Xcode中
    • 移动的已知良好实现 numberOfSectionsInTableView: tableView:numberOfRowsInSection: 到新的子类
    • 表格控制器 现有的 UIView / UITableView 将为此自动创建的 表格控制器 ,然后设置 表格控制器 的类来匹配新的子类
    • 数据源 代表 连接并将其连接到新的 表格控制器

    完成后,我没有工作时间 . 我最终得到了三种结果中的一种,这三种结果似乎是随机发生的:

    • UITableView 加载时,我收到一个运行时错误,指示我正在发送 tableView:cellForRowAtIndexPath: 对一个不认识它的物体
    • UITableView
    • 没有错误,但是 不出现

    经过一些调试并创建了一个基本项目来重现这个问题,我通常会看到上面的第三个选项(没有错误但没有可见的表视图)。我添加了一些NSLog调用,发现尽管 NumberOfSectionsTableView: numberOfRowsInSection: cellForRowAtIndexPath: 事实并非如此。我确信我错过了一些非常简单的东西,我希望答案对比我更有经验的人来说是显而易见的。如果这不是一个简单的答案,我很乐意用一些代码或一个示例项目进行更新。谢谢你的时间!

    完成复制步骤:

    • TableTest
    • 打开 TableTestViewController.xib 在Interface Builder中,拖动 UITableView 在提供的视图表面上。
    • 连接 UITableView 代表 -文件所有者的出口,该所有者应已代表 TableTestViewController
    • 回到Xcode,将以下代码添加到 TableTestViewController.m:

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        NSLog(@"Returning num sections");
        return 1;
    }
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        NSLog(@"Returning num rows");
        return 1;
    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        NSLog(@"Trying to return cell");
        static NSString *CellIdentifier = @"Cell";
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
        }
        cell.text = @"Hello";
        NSLog(@"Returning cell");
        return cell;
    }
    
    • 建造和运行,你应该看到这个词 Hello 出现在 UITableView

    • 现在尝试移动这个 UITableView 表格控制器 子类并调用该类 TableTestTableViewController

    • 从中删除上述代码段 TableTestViewController.m 然后把它放进 TableTestTableViewController.m ,将这三种方法的默认实现替换为我们的。
    • 在同一个窗口中返回Interface Builder TableTestViewController.xib -文件,拖动一个 进入主IB窗口并删除新的 UITableView 自动附带的对象
    • 表格控制器
    • 移除 代表 来自现有的、以前工作的 UITableView 并将相同的两个绑定重新连接到新的 TableTestTableViewController 我们创造了。
    • 保存更改,构建并运行,如果您得到了我得到的结果,请注意 UITableView 不再正常工作

    解决方案: iPhone Developer Forums ,我已经记录了一个解决方案!主要 UIViewController TableTestViewController.h ):

    #import "TableTestTableViewController.h"
    

    IBOutlet TableTestTableViewController *myTableViewController;
    

    TableTestTableViewController 在主IB窗口中。XIB的UI部分不需要更改。即使没有用户代码直接使用它,只要将这个插座安装到位,就可以完全解决问题。感谢那些提供帮助的人,在iPhone开发者论坛上找到解决方案的BaldEagle功不可没。

    4 回复  |  直到 12 年前
        1
  •  23
  •   Jason Plank Maksim Kondratyuk    13 年前

    我按照你的步骤重新创建了项目,遇到了同样的问题。基本上你就快到了。缺少两件事(一旦修复,它就会工作):

    • 你需要连接网络 tableView TableTestTableViewController UITableView 你已经在屏幕上看到了。正如我之前所说,因为它不是 IBOutlet 您可以覆盖 桌面视图 IBOutlet :

      @interface TableTestTableViewController : UITableViewController {
          UITableView *tableView;
      }
      
      @property (nonatomic, retain) IBOutlet UITableView *tableView;
      
    • 下一步是添加对 并将其保留在 TableTestViewController . 否则你的 TableTestTableViewController 可能会被释放(在加载nib后,没有任何东西挂在上面),这就是为什么您会看到不稳定的结果、崩溃或什么都没有显示的原因。为此,请添加:

      @interface TableTestViewController : UIViewController {
          TableTestTableViewController *tableViewController;
      }
      
      @property (nonatomic, retain) IBOutlet TableTestTableViewController  *tableViewController;
      

      并在界面生成器中将其连接到 TableTestTableViewController 例子

    有了以上这些,我的机器工作得很好。

    此外,我认为最好说明这一切背后的动机(而不仅仅是使用 UITableViewController 有自己的 UITableView ).在我的例子中,它是使用其他视图,而 在相同的内容屏幕上。因此,我可以添加其他 UILabels UIImages 在下面 UIView 并展示 UITableView 在它们下面或上面。

        2
  •  4
  •   pablasso Jordan    13 年前

    UITableView 当我把它嵌入一个单独的笔尖而不是主笔尖时,它不会出现。我终于在上面找到了你的讨论,并意识到这是因为我的 UITableViewController 没有被保留!显然,的委托和数据源属性 UITableView 没有标记“保留”,因此我的笔尖正在加载,但控制器被抛出。。。由于objective-c的奇迹,我得到了 来自此服务器的所有错误消息。。。我还是不明白它为什么没有坠毁。我知道我以前看过“发送给xxx的消息”。。。为什么不给我一个呢?!?

    我认为大多数开发人员都会假设,他们在接口生成器中构建的结构将保存在某个更大的上下文(Nib)中,而不受发布限制。我想我知道他们为什么这么做。。这样iPhone就可以在内存不足的情况下放下并重新装入部分笔尖。但是伙计,这很难理解。

    还有-关于连接视图。首先,如果您从UI构建器中拖入一个,您将看到它们连接了view属性(这是一个 IBOutlet tableView ,这似乎是内部设置的。事实上,除非您愿意,否则似乎没有必要设置视图 viewDidLoad 通知。我刚刚断开了我的 uitableview uitableviewcontroller (只设置了委托和数据源),而且显然工作正常。

        3
  •  3
  •   pablasso Jordan    13 年前

    是的,出于某种原因(如果有人知道原因,请插话) tableView 财产 UITableViewController 不作为 IBOutlet 即使它是公共财产。因此,当您使用Interface Builder时,您无法看到该属性以连接到其他属性 UITableView . 因此,在子类中,可以创建 标记为 IBOutlet 把它连接起来。

    对我来说,这一切似乎都很老套,而且是一种变通方法,但这似乎是唯一一种将 UITableViewController's UITableView 并将其放在UI层次结构中的其他位置。当我试图设计视图时遇到了同样的问题,视图中除了 UITableView 这就是我解决问题的方法。。。这是正确的方法吗???

        4
  •  2
  •   Michael Petrotta user3140870    12 年前

    我能做到这一点。我建立了一个非常好的仪表板,有4个桌面视图和一个带有视频的网络视图。关键是将单独的tableView控制器和IBOutlet连接到视图控制器中定义的其他tableView控制器。在UIB中,您只需要将其他tableview控制器连接到视图控制器的文件所有者。然后将表连接到数据源和委托的相应视图控制器。