If no Table View results, display "No Results" on screen

I have a tableview, where sometimes there might not be any results to list, so I would like to put something up that says "no results" if there are no results (either a label or one table view cell?).

Is there an easiest way to do this?

I would try a label behind the tableview then hide one of the two based on the results, but since I'm working with a TableViewController and not a normal ViewController I'm not sure how smart or doable that is.

I'm also using Parse and subclassing as a PFQueryTableViewController:

@interface TableViewController : PFQueryTableViewController

I can provide any additional details needed, just let me know!

TableViewController Scene in Storyboard:

enter image description here

EDIT: Per Midhun MP, here's the code I'm using

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger numOfSections = 0;
if ([self.stringArray count] > 0)
{
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
numOfSections                 = 1;
//yourTableView.backgroundView   = nil;
self.tableView.backgroundView = nil;
}
else
{
UILabel *noDataLabel         = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height)];
noDataLabel.text             = @"No data available";
noDataLabel.textColor        = [UIColor blackColor];
noDataLabel.textAlignment    = NSTextAlignmentCenter;
//yourTableView.backgroundView = noDataLabel;
//yourTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.backgroundView = noDataLabel;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}


return numOfSections;
}

And here's the View I'm getting, it still has separator lines. I get the feeling that this is some small change, but I'm not sure why separator lines are showing up?

enter image description here

72760 次浏览

I would present a an overlay view that has the look and message you want if the tableview has no results. You could do it in ViewDidAppear, so you have the results before showing/not showing the view.

你可以试试这个控制。它很整洁。 DZNEmptyDataSet

Or if I were you all I would do is

  • 检查数据数组是否为空
  • 如果它是空的,那么添加一个名为@“ No Data”的对象
  • 在 cell.textLabel.text 中显示该字符串

小菜一碟

我认为解决你的问题最优雅的方法是从 UITableViewController切换到包含 UITableViewUIViewController。这样你就可以添加任何你想要的 UIView作为主视图的子视图。

我不建议使用 UITableViewCell 来实现这一点,因为将来可能需要添加额外的东西,而且事情很快就会变得很糟糕。

您也可以这样做,但这也不是最好的解决方案。

UIWindow* window = [[UIApplication sharedApplication] keyWindow];
[window addSubview: OverlayView];

通过使用 UITableViewbackgroundView属性,可以很容易地实现这一点。

目标丙:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger numOfSections = 0;
if (youHaveData)
{
yourTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
numOfSections                = 1;
yourTableView.backgroundView = nil;
}
else
{
UILabel *noDataLabel         = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, yourTableView.bounds.size.width, yourTableView.bounds.size.height)];
noDataLabel.text             = @"No data available";
noDataLabel.textColor        = [UIColor blackColor];
noDataLabel.textAlignment    = NSTextAlignmentCenter;
yourTableView.backgroundView = noDataLabel;
yourTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}


return numOfSections;
}

Swift:

func numberOfSections(in tableView: UITableView) -> Int
{
var numOfSections: Int = 0
if youHaveData
{
tableView.separatorStyle = .singleLine
numOfSections            = 1
tableView.backgroundView = nil
}
else
{
let noDataLabel: UILabel  = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.bounds.size.height))
noDataLabel.text          = "No data available"
noDataLabel.textColor     = UIColor.black
noDataLabel.textAlignment = .center
tableView.backgroundView  = noDataLabel
tableView.separatorStyle  = .none
}
return numOfSections
}

参考资料 UITableView 类引用

backgroundView物业

表视图的背景视图。

声明

斯威夫特

var backgroundView: UIView?

目标 C

@property(nonatomic, readwrite, retain) UIView *backgroundView

讨论

表视图的背景视图将自动调整大小以匹配 此视图作为表的子视图放置 view behind all cells, header views, and footer views.

必须将此属性设置为 nil 才能设置 table view.

在您的 numberOfSectionsInTableView方法中使用此代码:-

if ([array count]==0
{


UILabel *fromLabel = [[UILabel alloc]initWithFrame:CGRectMake(50, self.view.frame.size.height/2, 300, 60)];
fromLabel.text =@"No Result";
fromLabel.baselineAdjustment = UIBaselineAdjustmentAlignBaselines;
fromLabel.backgroundColor = [UIColor clearColor];
fromLabel.textColor = [UIColor lightGrayColor];
fromLabel.textAlignment = NSTextAlignmentLeft;
[fromLabel setFont:[UIFont fontWithName:Embrima size:30.0f]];
[self.view addSubview:fromLabel];
[self.tblView setHidden:YES];
}

Swift Version of above code :-

func numberOfSectionsInTableView(tableView: UITableView) -> Int {


var numOfSection: NSInteger = 0


if CCompanyLogoImage.count > 0 {


self.tableView.backgroundView = nil
numOfSection = 1




} else {


var noDataLabel: UILabel = UILabel(frame: CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height))
noDataLabel.text = "No Data Available"
noDataLabel.textColor = UIColor(red: 22.0/255.0, green: 106.0/255.0, blue: 176.0/255.0, alpha: 1.0)
noDataLabel.textAlignment = NSTextAlignment.Center
self.tableView.backgroundView = noDataLabel


}
return numOfSection
}

但是,如果从 JSON 加载 Information,则需要检查 JSON 是否为空,因此,如果将这样的代码放入,最初会显示“ No data”消息,然后消失。因为在表重新加载数据之后,消息将隐藏。因此,您可以将加载 JSON 数据的代码放到一个数组中。所以:-

func numberOfSectionsInTableView(tableView: UITableView) -> Int {


return 1
}


func extract_json(data:NSData) {




var error: NSError?


let jsonData: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers , error: &error)
if (error == nil) {
if let jobs_list = jsonData as? NSArray
{
if jobs_list.count == 0 {


var noDataLabel: UILabel = UILabel(frame: CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height))
noDataLabel.text = "No Jobs Available"
noDataLabel.textColor = UIColor(red: 22.0/255.0, green: 106.0/255.0, blue: 176.0/255.0, alpha: 1.0)
noDataLabel.textAlignment = NSTextAlignment.Center
self.tableView.backgroundView = noDataLabel


}


for (var i = 0; i < jobs_list.count ; i++ )
{
if let jobs_obj = jobs_list[i] as? NSDictionary
{
if let vacancy_title = jobs_obj["VacancyTitle"] as? String
{
CJobTitle.append(vacancy_title)


if let vacancy_job_type = jobs_obj["VacancyJobType"] as? String
{
CJobType.append(vacancy_job_type)


if let company_name = jobs_obj["EmployerCompanyName"] as? String
{
CCompany.append(company_name)


if let company_logo_url = jobs_obj["EmployerCompanyLogo"] as? String
{
//CCompanyLogo.append("http://google.com" + company_logo_url)


let url = NSURL(string: "http://google.com" + company_logo_url )
let data = NSData(contentsOfURL:url!)
if data != nil {
CCompanyLogoImage.append(UIImage(data: data!)!)
}


if let vacancy_id = jobs_obj["VacancyID"] as? String
{
CVacancyId.append(vacancy_id)


}


}


}


}
}
}
}
}
}
do_table_refresh();




}


func do_table_refresh() {


dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
return
})
}

Swift3.0

I hope it server your purpose...... In your UITableViewController .

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive && searchController.searchBar.text != "" {
if filteredContacts.count > 0 {
self.tableView.backgroundView = .none;
return filteredContacts.count
} else {
Helper.EmptyMessage(message: ConstantMap.NO_CONTACT_FOUND, viewController: self)
return 0
}
} else {
if contacts.count > 0 {
self.tableView.backgroundView = .none;
return contacts.count
} else {
Helper.EmptyMessage(message: ConstantMap.NO_CONTACT_FOUND, viewController: self)
return 0
}
}
}

有功能的助手班:

 /* Description: This function generate alert dialog for empty message by passing message and
associated viewcontroller for that function
- Parameters:
- message: message that require for  empty alert message
- viewController: selected viewcontroller at that time
*/
static func EmptyMessage(message:String, viewController:UITableViewController) {
let messageLabel = UILabel(frame: CGRect(x: 0, y: 0, width: viewController.view.bounds.size.width, height: viewController.view.bounds.size.height))
messageLabel.text = message
let bubbleColor = UIColor(red: CGFloat(57)/255, green: CGFloat(81)/255, blue: CGFloat(104)/255, alpha :1)


messageLabel.textColor = bubbleColor
messageLabel.numberOfLines = 0;
messageLabel.textAlignment = .center;
messageLabel.font = UIFont(name: "TrebuchetMS", size: 18)
messageLabel.sizeToFit()


viewController.tableView.backgroundView = messageLabel;
viewController.tableView.separatorStyle = .none;
}

SWIFT 3

        let noDataLabel: UILabel     = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.bounds.size.height))
noDataLabel.text             = "No data available"
noDataLabel.textColor        = UIColor.white
noDataLabel.font             = UIFont(name: "Open Sans", size: 15)
noDataLabel.textAlignment    = .center
tableView.backgroundView = noDataLabel
tableView.separatorStyle = .none

Swift 3(更新) :

override func numberOfSections(in tableView: UITableView) -> Int {
if myArray.count > 0 {
self.tableView.backgroundView = nil
self.tableView.separatorStyle = .singleLine
return 1
}


let rect = CGRect(x: 0,
y: 0,
width: self.tableView.bounds.size.width,
height: self.tableView.bounds.size.height)
let noDataLabel: UILabel = UILabel(frame: rect)


noDataLabel.text = "Custom message."
noDataLabel.textColor = UIColor.white
noDataLabel.textAlignment = NSTextAlignment.center
self.tableView.backgroundView = noDataLabel
self.tableView.separatorStyle = .none


return 0
}

这是对我有效的解决方案。

  1. Add the following code to a new file.

  2. 将表类从情节串连板或.xib 更改为自定义类“ MyTableView”

(这只适用于第一部分。如果希望进行更多自定义,请相应地为其他部分更改 MyTableView reloadData ()函数

public class MyTableView: UITableView {


override public func reloadData() {
super.reloadData()


if self.numberOfRows(inSection: 0) == 0 {
if self.viewWithTag(1111) == nil {
let noDataLabel = UILabel()
noDataLabel.textAlignment = .center
noDataLabel.text = "No Data Available"
noDataLabel.tag = 1111
noDataLabel.center = self.center
self.backgroundView = noDataLabel
}


} else {
if self.viewWithTag(1111) != nil {
self.backgroundView = nil
}
}
}
}

用于 Xcode 8.3.2-Swift 3.1

这里有一个不太广为人知但是非常简单的方法,可以将“ No Items”视图添加到一个可以追溯到 Xcode 7的空表视图中。我将留给您来控制添加/删除表的背景视图的逻辑,但下面是 Xcode (8.3.2)情节串连图:

  1. Select the scene in the Storyboard that has your table view.
  2. 拖动一个空的 UIView 到该场景的“场景码头”

enter image description here

  1. 向新视图添加 UILabel 和任何约束,然后为该视图创建 IBOutlet

enter image description here

  1. 将该视图分配给 tableView.backoundView

enter image description here

  1. 看看这神奇的力量!

enter image description here

Ultimately this works anytime you want to add a simple view to your view controller that you don't necessarily want to be displayed immediately, but that you also don't want to hand code.

如果您不使用 tableview 页脚,并且不希望 tableview 用空的默认表单元格填充屏幕,我建议您将 tableview 页脚设置为空的 UIView。我不知道在 obj-c 或 Swift 中的正确语法,但是在 Xamarin.iOS 中,我会这样做:

public class ViewController : UIViewController
{
UITableView _table;


public ViewController (IntPtr handle) : base (handle)
{
}


public override void ViewWillAppear(bool animated) {
// Initialize table


_table.TableFooterView = new UIView();
}
}

上面的代码将导致一个没有空单元格的表格视图

将此代码添加到一个文件中,并将集合类型更改为 CustomCollectionView

import Foundation


class CustomCollectionView: UICollectionView {


var emptyModel = EmptyMessageModel()
var emptyView: EmptyMessageView?
var showEmptyView: Bool = true


override func reloadData() {
super.reloadData()


emptyView?.removeFromSuperview()
self.backgroundView = nil


if !showEmptyView {
return
}


if numberOfSections < 1 {
let rect = CGRect(x: 0,
y: 0,
width: self.bounds.size.width,
height: self.bounds.size.height)


emptyView = EmptyMessageView()
emptyView?.frame = rect
if let emptyView = emptyView {
//                self.addSubview(emptyView)
self.backgroundView = emptyView
}
emptyView?.setView(with: emptyModel)


} else {
emptyView?.removeFromSuperview()
self.backgroundView = nil
}
}
}


class EmptyMessageView: UIView {


@IBOutlet weak var messageLabel: UILabel!
@IBOutlet weak var imageView: UIImageView!


var view: UIView!


override init(frame: CGRect) {
super.init(frame: frame)
xibSetup()
}


required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
xibSetup()
}


func xibSetup() {
view = loadViewFromNib()


view.frame = bounds


view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(view)
}


func loadViewFromNib() -> UIView {


let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: "EmptyMessageView", bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView


return view
}


func setView(with model: EmptyMessageModel) {
messageLabel.text = model.message ?? ""
imageView.image = model.image ?? #imageLiteral(resourceName: "no_notification")
}
}


///////////
class EmptyMessageModel {
var message: String?
var image: UIImage?


init(message: String = "No data available", image: UIImage = #imageLiteral(resourceName: "no_notification")) {
self.message = message
self.image = image
}
}

如果您想在没有任何代码的情况下执行此操作,请尝试这样做!

点击 tableView。

tableView Screenshot

将样式从“普通”更改为“分组”。

Table View properties screenshot-2

现在当你用..。

Background 视图 = 插入您的标签或视图

它不会显示分离器!