当我的UITableView还没有数据时,如何显示占位符图像?

时间:2009-05-18 22:54:08

标签: iphone uinavigationcontroller uitableview

我有一个应用程序,在加载时,会显示一个UITableView,其中包含用户的数据。

然而,当用户第一次加载应用程序时(在他们创建任何数据之前),我想显示背景图像而不是空表(带箭头指向)到'添加记录'导航栏按钮)。用户添加了第一条记录后,将显示tableview。我见过很多应用程序这样做 - 目前我能想到的唯一例子是Cha-Ching,在你设置任何预算/等之前。但是,我不能为我的生活做出如何做到这一点。

我最初在主窗口的xib中添加了一个navigationcontroller,其rootViewController是一个自定义的viewcontroller / xib。这个rootViewController包含背景图像,上面有一个隐藏的tableview,以及一个管理tableview的自定义tableviewcontroller。这似乎工作正常,如果有数据,它将加载并显示在表中。但是,如果我要在屏幕外滚动数据,应用程序会崩溃,并出现此错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'*** -[UITextEffectsWindow tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0xd2d130'

我不知道UITextEffectsWindow是什么,或者为什么它试图管理我的tableview。我认为在我的视图层次结构中可能会错误地连接某些内容......

如果有更简单/更直接的方式,我会非常感激,如果有人能够解释它。你会怎么做?

提前致谢。

5 个答案:

答案 0 :(得分:1)

这是迄今为止我满意的一个解决方案。

首先,我创建了一个与我的TableView大小相同的透明视图。每当TableView的数据源中没有数据时,我都会将此视图添加为TableView的兄弟。我可以在数据可用时完全删除视图,因为透明度会影响使用TableView的滚动动画的平滑度。

我只是在这个视图中添加了一个透明标签,说明“无数据可用”的效果。为这个标签添加一点阴影确实有助于强化标签在空TableView顶部“浮动”的概念。

我喜欢你使用图像的方法。如果你不需要像我现在那样本地化一个字符串,它可能会保存你的工作。

答案 1 :(得分:1)

为了实现这一点,使用UITableViewController子类作为我唯一的视图(根据Apple模板在UINavigationController中),我使用了以下方法:

  1. 在XIB中创建一个包含UITableViewController和tableView的tableView大小的UIView。

  2. 将带有占位符图像的ImageView集添加到UIView。

  3. 将UIView作为IBOutlet连接(在下面的示例代码中,我称之为emptyTableView)

  4. 何时从UITableViewController子类中显示占位符:

    [self.tableView addSubView:emptyTableView]; [self.tableView setScrollEnabled:FALSE];

  5. 禁用滚动是必要的,否则用户将能够上下移动占位符图像。只需记住在用户添加项目后启用它。

    1. 删除图片视图

      [emptyTableView removeFromSuperview];

答案 2 :(得分:1)

为此,我使用以下控制器而不是UITableViewController。当表空时,它会自动在表上放置一个视图,并在填充时将其删除。

只需拨打[self reloadData]而不是[self.tableView reloadData],以便检查该表是否为空。

在您的子类中,实现一个makeEmptyOverlayView函数,该函数将创建显示在空表上的视图。

@interface MyTableViewController : UITableViewController
{
      BOOL hasAppeared;
      BOOL scrollWasEnabled;
      UIView *emptyOverlay;
}

- (void) reloadData;
- (void) checkEmpty;

@end

@implementation MyTableViewController

- (void)viewWillAppear:(BOOL)animated
{
   [self reloadData];
   [super viewWillAppear: animated];
}

- (void)viewDidAppear:(BOOL)animated
{
   hasAppeared = YES;

   [super viewDidAppear: animated];

   [self checkEmpty];
}

- (void)viewDidUnload
{
   if (emptyOverlay)
   {
      self.tableView.scrollEnabled = scrollWasEnabled;
      [emptyOverlay removeFromSuperview];
      emptyOverlay = nil;
   }
}

- (void) reloadData
{
   [self.tableView reloadData];

   if (hasAppeared &&
       [self respondsToSelector: @selector(makeEmptyOverlayView)])
      [self checkEmpty];
}

- (void) checkEmpty
{
   BOOL isEmpty(YES);

   id<UITableViewDataSource> src(self.tableView.dataSource);
   NSInteger sections(1);
   if ([src respondsToSelector: @selector(numberOfSectionsInTableView:)])
      sections = [src numberOfSectionsInTableView: self.tableView];
   for (int i(0); i<sections; ++i)
   {
      NSInteger rows([src tableView: self.tableView numberOfRowsInSection: i]);
      if (rows)
         isEmpty = NO;
   }

   if (!isEmpty != !emptyOverlay)
   {
      if (isEmpty)
      {
         scrollWasEnabled = self.tableView.scrollEnabled;
         self.tableView.scrollEnabled = NO;
         emptyOverlay = [self makeEmptyOverlayView];
         [self.tableView addSubview: emptyOverlay];
         [emptyOverlay release];
      }
      else
      {
         self.tableView.scrollEnabled = scrollWasEnabled;
         [emptyOverlay removeFromSuperview];
         emptyOverlay = nil;
      }
   }
   else if (isEmpty)
   {
      // Make sure it is still above all siblings.
      [emptyOverlay retain];
      [emptyOverlay removeFromSuperview];
      [self.tableView addSubview: emptyOverlay];
      [emptyOverlay release];
   }
}

@end

答案 3 :(得分:0)

如果您使用Three20,则可以在填充表格之前轻松地将所需的任何图像设置为占位符。

答案 4 :(得分:0)

所以,为了解决这个问题,我在上面的评论中讨论过:

我创建了一个普通的UIViewController子类,它包含一个UIImageView和一个UITableView。 viewController符合UITableViewDelegate和UITableViewDatasource协议,并负责管理tableView。 viewController类根据数据是否可用简单地显示或隐藏imageView。

我之前尝试使用UITableViewController管理这些视图时出错了。 UITableViewController必须有一个tableView作为其视图,而使用此解决方案,viewController可以包含image和tableView,并实现管理tableView所需的协议。

感谢您的帮助!