web-dev-qa-db-ja.com

テーブルビューの結果がない場合は、画面に「結果なし」と表示します

リストに結果が表示されない場合があるtableviewがあるので、「結果なし」というものを表示したい結果がない場合(ラベルまたはテーブルビューのいずれか)細胞?)。

これを行う最も簡単な方法はありますか?

labelの後ろでtableviewを試してから、結果に基づいて2つのうちの1つを非表示にしますが、通常のTableViewControllerではなくViewControllerで作業しているため、それが可能です。

また、Parseを使用し、PFQueryTableViewControllerとしてサブクラス化しています。

@interface TableViewController : PFQueryTableViewController

必要な追加情報を提供できますが、お知らせください!

TableViewControllerストーリーボードのシーン:

enter image description here

編集: Midhun MPあたり、私が使用しているコードはこちら

- (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;
}

そして、ここに私が取得しているビューがありますが、まだセパレーターラインがあります。これは小さな変更であると感じますが、なぜセパレーターラインが表示されるのか分かりませんか?

enter image description here

103
SRMR

backgroundViewUITableViewプロパティを使用することで簡単に実現できます。

目的C:

- (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;
}

スイフト:

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
}

参照 ITableViewクラス参照

backgroundViewプロパティ

テーブルビューの背景ビュー。

宣言

Swift

var backgroundView: UIView?

Objective-C

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

討論

テーブルビューの背景ビューは、テーブルビューのサイズに合わせて自動的にサイズ変更されます。このビューは、すべてのセル、ヘッダービュー、およびフッタービューの背後にあるテーブルビューのサブビューとして配置されます。

テーブルビューの背景色を設定するには、このプロパティをnilに設定する必要があります。

194
Midhun MP

Xcode 8.3.2の場合-Swift 3.1

Xcode 7に戻る空のテーブルビューに「アイテムなし」ビューを追加する、あまり知られていないが非常に簡単な方法を次に示します。ビューをテーブルの背景ビューに表示しますが、Xcode(8.3.2)ストーリーボードのフローは次のとおりです。

  1. ストーリーボードで、テーブルビューがあるシーンを選択します。
  2. 空のUIViewをそのシーンの「Scene Dock」にドラッグします

enter image description here

  1. UILabelと制約を新しいビューに追加し、そのビューのIBOutletを作成します

enter image description here

  1. そのビューをtableView.backgroundViewに割り当てます

enter image description here

  1. 魔法を見よ!

enter image description here

最終的にこれは、必ずしもすぐに表示される必要はないが、コードを渡したくない単純なビューをView Controllerに追加したいときにいつでも機能します。

92
Paul Bonneville

上記のコードのSwiftバージョン:-

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から情報をロードする場合は、JSONが空かどうかを確認する必要があります。そのため、このようなコードを入力すると、最初に「データなし」メッセージが表示されて消えます。テーブルがデータをリロードした後、メッセージが非表示になるためです。したがって、JSONデータを配列にロードする場所にこのコードを配置できます。 SO:-

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
    })
}
30

このコントロールを試すことができます。それはかなりきれいです。 DZNEmptyDataSet

または私があなただったら私がするすべては

  • データ配列が空かどうかを確認します
  • 空の場合は、@ "No Data"というオブジェクトを1つ追加します
  • Cell.textLabel.textにその文字列を表示します

やさしい

7
Sam B

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
}
5
Teodor Ciuraru

Swift3.

それがあなたの目的を果たすことを願っています...... 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;
        }
5

問題を解決する最もエレガントな方法は、UITableViewControllername__からUIViewControllername__を含むUITableViewname__に切り替えることだと思います。このようにして、必要なUIViewname__をメインビューのサブビューとして追加できます。

これを行うためにUITableViewCellを使用することはお勧めしません。将来さらに追加する必要がある場合があり、すぐに見苦しくなります。

このようなこともできますが、これも最善の解決策ではありません。

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

あなたの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];
}
3
Chandan

ここに私のために働いた解決策があります。

  1. 次のコードを新しいファイルに追加します。

  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
            }
        }
    }
}
2
ShrikantWalekar

スイフト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
2
Ahmed Safadi

コードなしでこれを行いたい場合は、これを試してください!

TableViewをクリックします。

tableView Screenshot

スタイルを「プレーン」から「グループ化」に変更します。

Table View properties screenshot-2

使用すると....

tableView.backgroundView =ラベルを挿入OR VIEW

セパレータは表示されません!

1
F. Morales

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();
    }
}

上記のコードは、空のセルのないテーブルビューになります

1
frmi

テーブルビューに結果がない場合は、必要な外観とメッセージを含むオーバーレイビューを表示します。 ViewDidAppearで実行できるため、ビューを表示/非表示する前に結果を取得できます。

1
Siriss

このコードを1つのファイルに追加し、コレクションタイプを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
  }
}
1
ShrikantWalekar