我有一个应用程序,在加载时,会显示一个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。我认为在我的视图层次结构中可能会错误地连接某些内容......
如果有更简单/更直接的方式,我会非常感激,如果有人能够解释它。你会怎么做?
提前致谢。
答案 0 :(得分:1)
这是迄今为止我满意的一个解决方案。
首先,我创建了一个与我的TableView大小相同的透明视图。每当TableView的数据源中没有数据时,我都会将此视图添加为TableView的兄弟。我可以在数据可用时完全删除视图,因为透明度会影响使用TableView的滚动动画的平滑度。
我只是在这个视图中添加了一个透明标签,说明“无数据可用”的效果。为这个标签添加一点阴影确实有助于强化标签在空TableView顶部“浮动”的概念。
我喜欢你使用图像的方法。如果你不需要像我现在那样本地化一个字符串,它可能会保存你的工作。
答案 1 :(得分:1)
为了实现这一点,使用UITableViewController子类作为我唯一的视图(根据Apple模板在UINavigationController中),我使用了以下方法:
在XIB中创建一个包含UITableViewController和tableView的tableView大小的UIView。
将带有占位符图像的ImageView集添加到UIView。
将UIView作为IBOutlet连接(在下面的示例代码中,我称之为emptyTableView)
何时从UITableViewController子类中显示占位符:
[self.tableView addSubView:emptyTableView]; [self.tableView setScrollEnabled:FALSE];
禁用滚动是必要的,否则用户将能够上下移动占位符图像。只需记住在用户添加项目后启用它。
删除图片视图
[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所需的协议。
感谢您的帮助!