빈 UITableView 처리. 친근한 메시지 인쇄


124

경우에 따라 비어있는 것이 합법적 인 UITableView가 있습니다. 따라서 앱의 배경 이미지를 표시하는 대신 다음과 같은 친숙한 메시지를 화면에 인쇄하는 것이 좋습니다.

이 목록은 현재 비어 있습니다.

가장 간단한 방법은 무엇입니까?


10
:이 프로젝트를 확인 github.com/dzenbot/DZNEmptyDataSet
oleynikd

@oleynikd 감사합니다 !!!!!
Luda 2018

답변:


173

UITableView의 backgroundView 속성은 친구입니다.

에서 viewDidLoad또는 어디서든 것을 reloadData당신이 당신의 테이블이 비어인지 아닌지 판단하고 UILabel의를 포함하는 UIView의와 jQuery과의 backgroundView의 속성을 업데이트하거나 전무로 설정해야합니다. 그게 다야.

물론 UITableView의 데이터 소스를 이중으로하고 특별한 "list is empty"셀을 반환하는 것이 가능합니다. 갑자기 numberOfRowsInSection:(NSInteger)section비어 있는지 확인하지 않은 다른 섹션의 행 수를 계산해야합니다. 또한 빈 메시지가있는 특수 셀을 만들어야합니다. 또한 빈 메시지를 수용하기 위해 셀의 높이를 변경해야한다는 사실을 잊지 마십시오. 이것은 모두 가능하지만 반창고 위에 반창고처럼 보입니다.


12
backgroundView가 최고의 솔루션이라고 생각합니다. 감사합니다!
Ferran Maylinch 2014 년

1
한 가지 단점은 테이블 뷰가 아래로 당겨지면 메시지가 해당 위치에 유지된다는 것입니다. 차라리 업데이트중인 앱 스토어 앱에서 좋아요를 누르고 싶습니다. 여기에 빈 메시지는 ... 스크롤 행동을 간다
테스트

스크롤하기 위해 빈 메시지가 필요한 경우 @testing 분명히 스크롤 계층 구조의 일부가 아니기 때문에 백그라운드 뷰를 사용할 수 없습니다. 빈 상태에 대해 사용자 정의 섹션과 UITableViewCell을 사용하고 싶을 것입니다.
LightningStryk

backgroundView숨겨진 속성을 전환 하는 것이 좋습니다. 함께 DZNEmptyDataSet, 우리는 사용해야emptyDataSetSource
onmyway133

버튼을 추가하려면 다음을 수행해야합니다. tableView.backgroundView!.userInteraction = true행 뒤에을 설정 tableView.backgroundView = constructMyViewWithButtons()하거나 설정하는 방법입니다.
kbpontius

90

Jhonston의 답변과 동일하지만 확장으로 선호했습니다.

import UIKit

extension UITableView {

    func setEmptyMessage(_ message: String) {
        let messageLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height))
        messageLabel.text = message
        messageLabel.textColor = .black
        messageLabel.numberOfLines = 0
        messageLabel.textAlignment = .center
        messageLabel.font = UIFont(name: "TrebuchetMS", size: 15)
        messageLabel.sizeToFit()

        self.backgroundView = messageLabel
        self.separatorStyle = .none
    }

    func restore() {
        self.backgroundView = nil
        self.separatorStyle = .singleLine
    }
}

용법:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if things.count == 0 {
        self.tableView.setEmptyMessage("My Message")
    } else {
        self.tableView.restore()
    }

    return things.count
}

제안 해 주셔서 감사합니다.
ssowri1

1
확장이 더 좋습니다! 감사.
Ogulcan 오르한

확장 기능을 좋아합니다 :)
Alix

1
섹션이있는 경우이 논리를 func numberOfSections(in tableView: UITableView) -> Int메서드 로 이동해야합니다.
craft

87

여기에 대한 답변을 기반으로에서 사용할 수있는 빠른 수업이 있습니다 UITableViewController.

import Foundation
import UIKit

class TableViewHelper {

    class func EmptyMessage(message:String, viewController:UITableViewController) {
        let rect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: self.view.bounds.size.width, height: self.view.bounds.size.height))
        let messageLabel = UILabel(frame: rect)
        messageLabel.text = message
        messageLabel.textColor = UIColor.blackColor()
        messageLabel.numberOfLines = 0;
        messageLabel.textAlignment = .Center;
        messageLabel.font = UIFont(name: "TrebuchetMS", size: 15)
        messageLabel.sizeToFit()

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

당신에 UITableViewController당신이 호출 할 수 있습니다numberOfSectionsInTableView(tableView: UITableView) -> Int

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    if projects.count > 0 {
        return 1
    } else {
        TableViewHelper.EmptyMessage("You don't have any projects yet.\nYou can create up to 10.", viewController: self)
        return 0
    }
}

여기에 이미지 설명 입력

http://www.appcoda.com/pull-to-refresh-uitableview-empty/ 의 약간의 도움으로


그래도 이미지를 추가하고 싶습니다. 그러나 훌륭한 빠른 솔루션입니다.
AnBisw 2017-06-26

10
대신 클래스의 확장을 사용 (뷰 컨트롤러를 통과하지 않음)
체사레

위의 코드를 사용할 수 없었지만 다른 사람들이 같은 문제를 겪을 경우를 대비하여이 답변 (첫 번째 답변)의 코드를 사용할 수있었습니다. - 또한 나는 2 대답 (장면 독 사용) 잘 작동 생각 stackoverflow.com/questions/28532926/...
르네 올슨

viewController.tableView.separatorStyle = .none필요하지 않습니다.
드미트리

17

다음 라이브러리를 권장합니다. DZNEmptyDataSet

프로젝트에 추가하는 가장 쉬운 방법은 다음과 같이 Cocaopods와 함께 사용하는 것입니다. pod 'DZNEmptyDataSet'

TableViewController에서 다음 import 문 (Swift)을 추가합니다.

import DZNEmptyDataSet

그런 다음에 반드시 수업 부합 함을 선언하게 DNZEmptyDataSetSource하고 DZNEmptyDataSetDelegate그래서 같은를 :

class MyTableViewController: UITableViewController, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate

귀하의에서 viewDidLoad다음 코드 줄을 추가합니다 :

tableView.emptyDataSetSource = self
tableView.emptyDataSetDelegate = self
tableView.tableFooterView = UIView()

이제 emptystate를 표시하기 위해해야 ​​할 일은 다음과 같습니다.

//Add title for empty dataset
func titleForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
    let str = "Welcome"
    let attrs = [NSFontAttributeName: UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)]
    return NSAttributedString(string: str, attributes: attrs)
}

//Add description/subtitle on empty dataset
func descriptionForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
    let str = "Tap the button below to add your first grokkleglob."
    let attrs = [NSFontAttributeName: UIFont.preferredFontForTextStyle(UIFontTextStyleBody)]
    return NSAttributedString(string: str, attributes: attrs)
}

//Add your image
func imageForEmptyDataSet(scrollView: UIScrollView!) -> UIImage! {
    return UIImage(named: "MYIMAGE")
}

//Add your button 
func buttonTitleForEmptyDataSet(scrollView: UIScrollView!, forState state: UIControlState) -> NSAttributedString! {
    let str = "Add Grokkleglob"
    let attrs = [NSFontAttributeName: UIFont.preferredFontForTextStyle(UIFontTextStyleCallout)]
    return NSAttributedString(string: str, attributes: attrs)
}

//Add action for button
func emptyDataSetDidTapButton(scrollView: UIScrollView!) {
    let ac = UIAlertController(title: "Button tapped!", message: nil, preferredStyle: .Alert)
    ac.addAction(UIAlertAction(title: "Hurray", style: .Default, handler: nil))
    presentViewController(ac, animated: true, completion: nil)
}

이 메소드는 필수가 아니며 버튼 등없이 빈 상태를 표시하는 것도 가능합니다.

Swift 4의 경우

// MARK: - Deal with the empty data set
// Add title for empty dataset
func title(forEmptyDataSet _: UIScrollView!) -> NSAttributedString! {
    let str = "Welcome"
    let attrs = [NSAttributedStringKey.font: UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)]
    return NSAttributedString(string: str, attributes: attrs)
}

// Add description/subtitle on empty dataset
func description(forEmptyDataSet _: UIScrollView!) -> NSAttributedString! {
    let str = "Tap the button below to add your first grokkleglob."
    let attrs = [NSAttributedStringKey.font: UIFont.preferredFont(forTextStyle: UIFontTextStyle.body)]
    return NSAttributedString(string: str, attributes: attrs)
}

// Add your image
func image(forEmptyDataSet _: UIScrollView!) -> UIImage! {
    return UIImage(named: "MYIMAGE")
}

// Add your button
func buttonTitle(forEmptyDataSet _: UIScrollView!, for _: UIControlState) -> NSAttributedString! {
    let str = "Add Grokkleglob"
    let attrs = [NSAttributedStringKey.font: UIFont.preferredFont(forTextStyle: UIFontTextStyle.callout), NSAttributedStringKey.foregroundColor: UIColor.white]
    return NSAttributedString(string: str, attributes: attrs)
}

// Add action for button
func emptyDataSetDidTapButton(_: UIScrollView!) {
    let ac = UIAlertController(title: "Button tapped!", message: nil, preferredStyle: .alert)
    ac.addAction(UIAlertAction(title: "Hurray", style: .default, handler: nil))
    present(ac, animated: true, completion: nil)
}

DZEmptyDataSet이 세로로 제대로 정렬되지 않는 문제가 있습니다. 누구든지 이와 같은 문제가 있습니까?
amariduran

12

이를 수행하는 한 가지 방법은 1행 수가 0 일 때 반환하도록 데이터 소스를 수정 하고 tableView:cellForRowAtIndexPath:메서드 에서 특수 목적 셀 (아마도 다른 셀 식별자 사용)을 생성하는 것입니다.

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSInteger actualNumberOfRows = <calculate the actual number of rows>;
    return (actualNumberOfRows  == 0) ? 1 : actualNumberOfRows;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSInteger actualNumberOfRows = <calculate the actual number of rows>;
    if (actualNumberOfRows == 0) {
        // Produce a special cell with the "list is now empty" message
    }
    // Produce the correct cell the usual way
    ...
}

유지 관리해야하는 테이블 뷰 컨트롤러가 여러 개있는 경우 누군가가 결국 제로 체크를 삽입하는 것을 잊기 때문에 다소 복잡해질 수 있습니다. 더 나은 접근 방식은 UITableViewDataSource구성 가능한 메시지가 포함 된 단일 행을 항상 반환 하는 별도의 구현 구현을 만드는 것입니다 (라고 부르겠습니다 EmptyTableViewDataSource). 테이블 뷰 컨트롤러에서 관리하는 데이터가 변경되면 변경을 관리하는 코드가 데이터가 비어 있는지 확인합니다. 비어 있지 않은 경우 일반 데이터 소스로 테이블보기 컨트롤러를 설정하십시오. 그렇지 않으면 EmptyTableViewDataSource적절한 메시지로 구성된 의 인스턴스로 설정하십시오 .


5
deleteRowsAtIndexPaths:withRowAnimation:반환 된 번호가 numberOfRowsInSection$ numRows-$ rowsDeleted의 결과와 일치해야 하므로 행이 삭제 된 테이블에서이 작업을 수행하는 데 문제가있었습니다 .
Animal451

4
나는 이것에 대해 적극 권장합니다. 엣지 케이스로 코드를 수수께끼로 만듭니다.
xtravar 2014 년

2
@xtravar 반대 투표보다는 자신의 답변을 게시하는 것이 좋습니다.
dasblinkenlight

1
나는 그 길을 걸어 왔고 그것은 자체적 인 문제로 이어진다. 내 경험상 거의 항상 Apple API를 대체하는 것보다 보강하는 것이 좋습니다.
xtravar 2014 년

1
이 솔루션은 NSFetchedResultsController에서 작동하지 않습니다. 대신 backgroundView 접근 방식을 시도해 보겠습니다.
Sam

10

나는 이것을 위해 titleForFooterInSection 메시지를 사용하고 있습니다. 이것이 차선책인지 아닌지는 모르겠지만 작동합니다.

-(NSString*)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section   {

    NSString *message = @"";
    NSInteger numberOfRowsInSection = [self tableView:self.tableView numberOfRowsInSection:section ];

    if (numberOfRowsInSection == 0) {
        message = @"This list is now empty";
    }

    return message;
}

2
좋은 속임수와 나에게 꽤 깨끗한 것 같습니다. 다음은 한 줄짜리입니다.return tableView.numberOfRowsInSection(section) == 0 ? "This list is now empty" : nil
TruMan1

8

따라서 더 안전한 솔루션을 위해 :

extension UITableView {
func setEmptyMessage(_ message: String) {
    guard self.numberOfRows() == 0 else {
        return
    }
    let messageLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height))
    messageLabel.text = message
    messageLabel.textColor = .black
    messageLabel.numberOfLines = 0;
    messageLabel.textAlignment = .center;
    messageLabel.font = UIFont.systemFont(ofSize: 14.0, weight: UIFontWeightMedium)
    messageLabel.sizeToFit()

    self.backgroundView = messageLabel;
    self.separatorStyle = .none;
}

func restore() {
    self.backgroundView = nil
    self.separatorStyle = .singleLine
}

public func numberOfRows() -> Int {
    var section = 0
    var rowCount = 0
    while section < numberOfSections {
        rowCount += numberOfRows(inSection: section)
        section += 1
    }
    return rowCount
  }
}

와에 대한 UICollectionView뿐만 아니라 :

extension UICollectionView {
func setEmptyMessage(_ message: String) {
    guard self.numberOfItems() == 0 else {
        return
    }

    let messageLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height))
    messageLabel.text = message
    messageLabel.textColor = .black
    messageLabel.numberOfLines = 0;
    messageLabel.textAlignment = .center;
    messageLabel.font = UIFont.systemFont(ofSize: 18.0, weight: UIFontWeightSemibold)
    messageLabel.sizeToFit()
    self.backgroundView = messageLabel;
}

func restore() {
    self.backgroundView = nil
}

public func numberOfItems() -> Int {
    var section = 0
    var itemsCount = 0
    while section < self.numberOfSections {
        itemsCount += numberOfItems(inSection: section)
        section += 1
    }
    return itemsCount
  }
}

보다 일반적인 솔루션 :

    protocol EmptyMessageViewType {
      mutating func setEmptyMessage(_ message: String)
      mutating func restore()
    }

    protocol ListViewType: EmptyMessageViewType where Self: UIView {
      var backgroundView: UIView? { get set }
    }

    extension UITableView: ListViewType {}
    extension UICollectionView: ListViewType {}

    extension ListViewType {
      mutating func setEmptyMessage(_ message: String) {
        let messageLabel = UILabel(frame: CGRect(x: 0,
                                                 y: 0,
                                                 width: self.bounds.size.width,
                                                 height: self.bounds.size.height))
        messageLabel.text = message
        messageLabel.textColor = .black
        messageLabel.numberOfLines = 0
        messageLabel.textAlignment = .center
        messageLabel.font = UIFont(name: "TrebuchetMS", size: 16)
        messageLabel.sizeToFit()

        backgroundView = messageLabel
    }

     mutating func restore() {
        backgroundView = nil
     }
}

7

나는 셀 뒤에있는 TableView 내부에 UITextView를 드래그 앤 드롭하는 것이 좋습니다. ViewController에 연결하고 적절한 때 (예 : 테이블이 다시로드 될 때마다) 숨기거나 표시합니다.

여기에 이미지 설명 입력


이것이 가장 쉬운 방법입니다)!
moonvader

사과처럼 고통스러운 두통; 이 아이디어에 대한 감사
Eenvincible

5

backgroundView를 사용하는 것은 좋지만 Mail.app 에서처럼 잘 스크롤되지 않습니다.

xtravar 와 비슷한 작업을 했습니다. 가 한 .

.NET Framework의 뷰 계층 구조 외부에 뷰를 추가했습니다 tableViewController. 계층

그런 다음 다음 코드를 사용했습니다 tableView:numberOfRowsInSection:.

if someArray.count == 0 {
    // Show Empty State View
    self.tableView.addSubview(self.emptyStateView)
    self.emptyStateView.center = self.view.center
    self.emptyStateView.center.y -= 60 // rough calculation here
    self.tableView.separatorColor = UIColor.clear
} else if self.emptyStateView.superview != nil {
    // Empty State View is currently visible, but shouldn't
    self.emptyStateView.removeFromSuperview()
    self.tableView.separatorColor = nil
}

return someArray.count

기본적으로 객체 emptyStateView의 하위보기로를 추가했습니다 tableView. 구분 기호가 뷰와 겹치므로 색상을 clearColor. 기본 구분자 색상으로 돌아가려면로 설정하면됩니다 nil.


이것은 꽤 잘 작동합니다! 그러나 예를 들어 당겨서 새로 고침 할 요소가있는 경우이 요소와 함께 스크롤되지 않습니다. 나는 그것이 더 나은을 설정하는 것으로 확인 tableHeaderView하고, 확인 이 맞게 크기를 조정합니다 .
Hannele

4

Container View Controller를 사용하는 것이 Apple 에 따르면 올바른 방법 입니다.

모든 빈 상태보기를 별도의 스토리 보드에 넣습니다. 각각 자체 UIViewController 하위 클래스 아래에 있습니다. 루트 뷰 바로 아래에 콘텐츠를 추가합니다. 작업 / 버튼이 필요한 경우 이제이를 처리 할 컨트롤러가 이미 있습니다.
그런 다음 해당 Storyboard에서 원하는 뷰 컨트롤러를 인스턴스화하고 자식 뷰 컨트롤러로 추가하고 컨테이너 뷰를 tableView의 계층 구조 (하위 뷰)에 추가하면됩니다. 빈 상태보기도 스크롤 할 수 있으므로 기분이 좋고 당겨서 새로 고침을 구현할 수 있습니다.

'콘텐츠에 자식보기 컨트롤러 추가'읽기 구현하는 방법에 대한 도움.

자식 뷰 프레임을로 설정했는지 확인하면 (0, 0, tableView.frame.width, tableView.frame.height)사물이 중앙에 올바르게 정렬됩니다.


3

첫째, 다른 대중적인 접근 방식의 문제점입니다.

BackgroundView

UILabel로 설정하는 간단한 경우를 사용하면 배경보기가 멋지게 가운데에 있지 않습니다.

메시지를 표시 할 셀, 머리글 또는 바닥 글

이것은 기능 코드를 방해하고 이상한 경우를 소개합니다. 메시지를 완벽하게 중앙에 배치하려면 다른 수준의 복잡성이 추가됩니다.

나만의 테이블 뷰 컨트롤러 롤링

refreshControl과 같은 기본 제공 기능을 잃고 휠을 다시 발명합니다. 유지 관리 가능한 최상의 결과를 얻으려면 UITableViewController를 사용하십시오.

UITableViewController를 자식 뷰 컨트롤러로 추가

iOS 7 이상에서 contentInset 문제로 끝날 것 같은 느낌이 듭니다. 왜 복잡한가요?

내 솔루션

내가 생각 해낸 최고의 해결책은 (그리고 이것이 이상적이지는 않다) 스크롤 뷰 위에 앉아 그에 따라 행동 할 수있는 특별한 뷰를 만드는 것입니다. 이것은 contentInset 광기로 iOS 7에서 분명히 복잡해 지지만 가능합니다.

주의해야 할 사항 :

  • 테이블 구분 기호는 reloadData 중에 어느 시점에서 맨 앞으로 가져옵니다.
  • contentInset / contentOffset-특별보기에서 해당 키를 관찰하십시오.
  • 키보드-키보드가 방해가되지 않도록하려면 다른 계산입니다.
  • 자동 레이아웃-보기 위치를 지정하기 위해 프레임 변경에 의존 할 수 없습니다.

하나의 UIView 하위 클래스에서이 문제를 한 번 파악하면 스피너로드, 뷰 비활성화, 오류 메시지 표시 등 모든 작업에 사용할 수 있습니다.


답변을 자세히 설명해 주시겠습니까? 테이블이 비어 있는지 어떻게 알 수 있습니까? 그런 다음 "그에 따라 행동"합니다.
Michael Ozeryansky 2014

테이블을 채우는 사람이기 때문에 테이블이 비어 있음을 알고 있습니다. 따라서 뷰 컨트롤러에는 비동기 로딩 콜백이 있습니다. 해당 콜백에서 if (itemsToShow.count == 0) {스크롤 뷰에 뷰 추가}. 까다로운 부분은 상단 뷰 ( '실드 / 메시지 뷰')를 스크롤 뷰의 전체 프레임을 차지하고 contentInset을 뺀 값으로 배치하여 메시지가 세로 중앙에 오도록하는 것입니다.
xtravar 2014

테이블보기 위에보기를 추가하는 방법은 무엇입니까? self.view는 테이블 뷰이고 내가 사용 addSubView하면 항상 자동 레이아웃에 문제를 일으키는 테이블 뷰에 첨부됩니다.
테스트

테이블 뷰 내에 배치하는 뷰는 자동 레이아웃을 사용하지 않아야하며 테이블 뷰 자체는 자동 레이아웃을 사용하지 않습니다.
xtravar 2014

1
한 가지 접근 방식을 놓쳤습니다. 당신은있는 UITableViewController를 사용하고 정기적있는 UIViewController에 아이 뷰 컨트롤러로 추가 할 수 있습니다
user1169629

3

이것이 가장 좋고 간단한 솔루션입니다.

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 60)];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 60)];
label.text = @"This list is empty";
label.center = self.view.center;
label.textAlignment = NSTextAlignmentCenter;
[view addSubview:label];

self.tableView.backgroundView = view;

2

빈 목록, UITableView 또는 UICollectionView에 대한 메시지를 표시 합니다.

extension UIScrollView {
    func showEmptyListMessage(_ message:String) {
        let rect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: self.bounds.size.width, height: self.bounds.size.height))
        let messageLabel = UILabel(frame: rect)
        messageLabel.text = message
        messageLabel.textColor = .black
        messageLabel.numberOfLines = 0
        messageLabel.textAlignment = .center
        messageLabel.font = UIFont.systemFont(ofSize: 15)
        messageLabel.sizeToFit()

        if let `self` = self as? UITableView {
            self.backgroundView = messageLabel
            self.separatorStyle = .none
        } else if let `self` = self as? UICollectionView {
            self.backgroundView = messageLabel
        }
    }
}

사용법 :

if cellsViewModels.count == 0 {
    self.tableView.showEmptyListMessage("No Product In List!")
}

또는:

if cellsViewModels.count == 0 {
    self.collectionView?.showEmptyListMessage("No Product In List!")
}

기억 : 새로 고침 후 데이터가 올 경우를 대비하여 메시지 레이블을 제거하는 것을 잊지 마십시오.


1
if messages.count! = 0 {show}
Eddwin Paz

1

스토리 보드에서 tableviewController 장면을 선택하십시오.

여기에 이미지 설명 입력

드래그 앤 드롭 UIView 메시지와 함께 라벨 추가 (예 : 데이터 없음)

여기에 이미지 설명 입력

TableViewController에 UIView (예 : yournoDataView)의 콘센트를 만듭니다.

그리고 viewDidLoad에서

self.tableView.backgroundView = yourNoDataView


1

Swift 4.2 사용

  func numberOfSections(in tableView: UITableView) -> Int
{
    var numOfSections: Int = 0
    if self.medArray.count > 0
    {
        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  Medicine available.Press + to add New Pills "
        noDataLabel.textColor     = UIColor.black
        noDataLabel.textAlignment = .center
        tableView.backgroundView  = noDataLabel
        tableView.separatorStyle  = .none
    }
    return numOfSections
}

1

이것을 Base 클래스에 추가 할 수 있습니다.

var messageLabel = UILabel()

func showNoDataMessage(msg: String) {
    let rect = CGRect(origin: CGPoint(x: 0, y :self.view.center.y), size: CGSize(width: self.view.bounds.width - 16, height: 50.0))
    messageLabel = UILabel(frame: rect)
    messageLabel.center = self.view.center
    messageLabel.text = msg
    messageLabel.numberOfLines = 0
    messageLabel.textColor = Colors.grayText
    messageLabel.textAlignment = .center;
    messageLabel.font = UIFont(name: "Lato-Regular", size: 17)
    self.view.addSubview(messageLabel)
    self.view.bringSubviewToFront(messageLabel)
}

API에서 데이터를 가져올 때 클래스에서 다음과 같이 표시하십시오.

func populateData(dataSource : [PRNJobDataSource]){
    self.dataSource = dataSource
    self.tblView.reloadData()
    if self.dataSource.count == 0 {self.showNoDataMessage(msg: "No data found.")}
}

이렇게 숨기세요.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if self.dataSource.count > 0 {self.hideNoDataMessage()}
    return dataSource.count
}

func hideNoDataMessage(){
    messageLabel.removeFromSuperview()
}

Hey @ Mudassir-Asghar hideNoDataMessage 함수는 어떻게 생겼습니까?
Saamer

1
안녕하세요, @Saamer 저는 위의 답변을 업데이트했습니다. 지적 해 주셔서 감사합니다. 도움이되기를 바랍니다. :)
Mudassir Asghar

0

스위프트 버전이지만 더 좋고 단순한 형태. ** 3.0

나는 그것이 당신의 목적을 달성하기를 바랍니다.

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

0

아마도 가장 좋은 해결책은 아니지만 테이블 하단에 레이블을 붙이고 행이 0이면 텍스트를 할당합니다. 매우 쉽고 몇 줄의 코드로 수행하려는 작업을 수행합니다.

내 테이블에는 두 개의 섹션이 있습니다 (직업 및 학교)

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if (jobs.count == 0 && schools.count == 0) {
        emptyLbl.text = "No jobs or schools"
    } else {
        emptyLbl.text = ""
    }

원하는 경우 count = 0 일 때 레이블을 빈 이미지 뷰로 바꿀 수도 있습니다.
Zach

0

이 작업을 수행하는 가장 쉽고 빠른 방법은 레이블을 tableView 아래의 측면 패널로 드래그하는 것입니다. 레이블 및 tableView에 대한 콘센트를 만들고 필요에 따라 레이블과 테이블을 숨기고 표시하는 if 문을 추가합니다. 또는 tableView.tableFooterView = UIView (frame : CGRect.zero) 이것을 viewDidLoad ()에 추가하여 빈 테이블에 테이블과 배경 뷰가 동일한 색상을 갖는 경우 숨겨진 인식을 제공 할 수 있습니다.


(이 게시물은 질문에 대한 양질의 답변 을 제공하지 않는 것 같습니다 . 답변 을 수정하고 더 자세한 정보로 완성하거나 질문에 대한 의견으로 게시하십시오).
sɐunıɔ ןɐ qɐp

0

수를 수동으로 확인할 필요가 없도록 몇 가지 사항을 변경했으며, 아래 표시된 메시지 크기에 상관없이 아무 문제가 없도록 레이블에 대한 제약 조건을 추가했습니다.

extension UITableView {

    fileprivate func configureLabelLayout(_ messageLabel: UILabel) {
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        let labelTop: CGFloat = CGFloat(UIDevice.current.userInterfaceIdiom == .pad ? 25:15)
        messageLabel.topAnchor.constraint(equalTo: backgroundView?.topAnchor ?? NSLayoutAnchor(), constant: labelTop).isActive = true
        messageLabel.widthAnchor.constraint(equalTo: backgroundView?.widthAnchor ?? NSLayoutAnchor(), constant: -20).isActive = true
        messageLabel.centerXAnchor.constraint(equalTo: backgroundView?.centerXAnchor ?? NSLayoutAnchor(), constant: 0).isActive = true
    }

    fileprivate func configureLabel(_ message: String) {
        let messageLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height))
        messageLabel.textColor = .black
        messageLabel.numberOfLines = 0
        messageLabel.textAlignment = .center
        let fontSize = CGFloat(UIDevice.current.userInterfaceIdiom == .pad ? 25:15)
        let font: UIFont = UIFont(name: "MyriadPro-Regular", size: fontSize) ?? UIFont()
        messageLabel.font = font
        messageLabel.text = message
        self.backgroundView = UIView()
        self.backgroundView?.addSubview(messageLabel)
        configureLabelLayout(messageLabel)
        self.separatorStyle = .none
    }

    func setEmptyMessage(_ message: String, _ isEmpty: Bool) {
        if isEmpty { // instead of making the check in every TableView DataSource in the project
            configureLabel(message)
        }
        else {
            restore()
        }

    }

    func restore() {
        self.backgroundView = nil
        self.separatorStyle = .singleLine
    }
}

용법

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let message: String = "The list is empty."
        ticketsTableView.setEmptyMessage(message, tickets.isEmpty)
        return self.tickets.count
    }

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.