테이블보기 결과가 없으면 화면에 "결과 없음"을 표시합니다.


114

나는이 tableview내가 그래서 가끔, 목록에 대한 결과가되지 않을 수 있습니다 곳, 즉 "결과가"말한다까지 뭔가를 넣어 싶습니다 어떤 결과가없는 경우 (라벨 또는 하나 개의 테이블 뷰 셀 중 하나가?).

이를 수행하는 가장 쉬운 방법이 있습니까?

나는 시도 할 label뒤에서 tableview결과에 따라 두의 다음 숨기기 하나,하지만 난 함께 일하고 있어요 때문에 TableViewController정상을하지 ViewController내가 얼마나 똑똑한 지 확실하지 않다거나 즉 드리겠습니다.

나는 또한 다음 Parse과 같이 사용 하고 서브 클래 싱하고 있습니다 PFQueryTableViewController.

@interface TableViewController : PFQueryTableViewController

필요한 추가 세부 정보를 제공 할 수 있습니다. 알려주세요.

TableViewController 스토리 보드의 장면 :

여기에 이미지 설명 입력

편집 : 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;
}

그리고 여기 내가 얻은보기가 있습니다. 여전히 구분선이 있습니다. 이것이 작은 변화라는 느낌이 들지만 구분선이 왜 나타나는지 잘 모르겠습니다.

여기에 이미지 설명 입력


트릭은 줄을 없애기 위해 tableview에 빈 footerView를 설정하는 것이라고 생각합니다.
Ben Sinclair

@Andy 그게 무슨 뜻이야?
SRMR

이 질문에 추가 된 솔루션을 사용하지 마십시오. 테이블보기 데이터 소스 메서드는 예상보다 더 많은 작업을 수행해서는 안됩니다. numberOfSections카운트를 반환해야합니다. 동일에 대한 numberOfRowsInSection. 언제든지 여러 번 호출 할 수 있습니다. 뷰를 업데이트하거나 데이터를 업데이트하거나 개수를 반환하는 것 외에는 아무것도하지 마십시오. 뷰 업데이트 논리는 이러한 메서드에 있어서는 안됩니다.
rmaddy

답변:


206

backgroundView속성을 사용하여 쉽게 얻을 수 있습니다 UITableView.

목표 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
}

참조 UITableView 클래스 참조

backgroundView 특성

테이블보기의 배경보기입니다.

선언

빠른

var backgroundView: UIView?

목표 -C

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

토론

테이블보기의 배경보기는 테이블보기의 크기에 맞게 자동으로 크기가 조정됩니다. 이보기는 모든 셀, 머리글보기 및 바닥 글보기 뒤에 테이블보기의 하위보기로 배치됩니다.

테이블 뷰의 배경색을 설정하려면이 속성을 nil로 설정해야합니다.


답변 해주셔서 감사합니다! 이것은 tableView내가 할 수 있도록 콘센트 가 필요하다는 것을 의미합니까 yourTableView.backgroundView? 나는를 사용하고 TableViewController있어서 지금은 콘센트가 없어서 궁금합니다.
SRMR

1
UITableViewController이미이라는 속성이 tableView하나를 만들 필요가 없습니다
Cihan 테크에게

알겠습니다. 사용self.tableView
SRMR 2015

1
보정. 추가 테스트에서 실제로 언급 한 라인이 동일한 값을 반환하도록 만들어야했습니다. numOfSections = 1. 0으로 만들고 테이블 뷰가 비어 있으면 작동하지만 셀을 만든 다음 삭제하면 메시지를 삭제하고 표시하는 대신 다음 오류와 함께 충돌이 발생합니다. *** 포착되지 않은 예외 'NSInternalInconsistencyException'으로 인해 앱 종료, 이유 : 'UITableView 내부 버그 : 이전 섹션 수 : 1 및 새 섹션 수 : 0으로 새 섹션 맵을 생성 할 수 없음'. 동일한 값을 반환하는 이유는 모르겠지만 제대로 작동하고 작동합니다.
ChrisOSX

2
이 솔루션을 사용하지 마십시오. 테이블보기 데이터 소스 메서드는 예상보다 더 많은 작업을 수행해서는 안됩니다. numberOfSections카운트를 반환해야합니다. 동일에 대한 numberOfRowsInSection. 언제든지 여러 번 호출 할 수 있습니다. 뷰를 업데이트하거나 데이터를 업데이트하거나 개수를 반환하는 것 외에는 아무것도하지 마십시오. 뷰 업데이트 논리는 이러한 메서드에 있어서는 안됩니다.
rmaddy

107

Xcode 8.3.2-Swift 3.1 용

다음은 Xcode 7로 돌아가는 빈 테이블 뷰에 "No Items"뷰를 추가 할 수있는 아주 잘 알려지지 않았지만 믿을 수 없을 정도로 쉬운 방법입니다. 테이블의 배경보기를 볼 수 있지만 다음은 Xcode (8.3.2) 스토리 보드의 흐름입니다.

  1. 테이블보기가있는 스토리 보드에서 장면을 선택합니다.
  2. 빈 UIView를 해당 장면의 "Scene Dock"으로 드래그합니다.

여기에 이미지 설명 입력

  1. 새보기에 UILabel 및 제약 조건을 추가 한 다음 해당보기에 대한 IBOutlet을 만듭니다.

여기에 이미지 설명 입력

  1. 해당 뷰를 tableView.backgroundView에 할당하십시오.

여기에 이미지 설명 입력

  1. 마법을 보라!

여기에 이미지 설명 입력

궁극적으로 이것은 즉시 표시되고 싶지는 않지만 코드를 작성하고 싶지 않은 뷰 컨트롤러에 간단한 뷰를 추가하려는 경우 언제든지 작동합니다.


1
이 기술은 간단한보기가 필요한 모든 작업에 적용됩니다. 사용자 정의 테이블 섹션 헤더에도 사용했습니다. 정말보기가 필요한 모든 것에 사용할 수 있습니다. IBOutlet을 통해 참조하고 사용자 정의보기가 필요한 모든 곳에 하위보기로 추가하십시오.
Paul Bonneville

@gmogames가 말했듯이, 2 년 동안 IOS를 수행 한 후 이것은 tableView 배경에 대해 처음으로 알게되었습니다!. 덕분에 남자
알리 아딜

1
감사합니다. 거기에 넣기 위해 tableView.separatorStyle = .none을 사용하고 backgroundView를 보려면 기본 UIView의 크기를 조정해야했습니다. 나는 스위프트 4와 엑스 코드 9.4을 사용하고 있습니다
하마드 타리크

사용자 정의보기를 어떻게 배치합니까?
Nol4635

1
@ Nol4635 테이블 뷰 배경의 경우 IBOutlet으로 만든 뷰를 테이블 뷰의 배경에 할당하거나 뷰를 다른 뷰에 추가하려는 경우 하위 뷰로 추가 할 수 있습니다. 프레임 값을 설정해야하지만 다른보기와 같습니다.
Paul Bonneville

30

위 코드의 신속한 버전 :-

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 데이터를 배열로로드하는 곳에이 코드를 넣을 수 있습니다. 그래서 :-

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

이것은 행에 데이터가 없을 때 레이블을 표시하는 데 매우 효과적입니다. 그러나 데이터가 들어오고 self.tableView.reloadData()호출 될 때 처리하는 가장 좋은 방법은 무엇 입니까? 새 행을 추가하는 것을 발견했지만 noDataLabel여전히 그 아래에 표시됩니다.
tylerSF

1
당신은 배열 항목은 self.tableView.backgroundView = nil을 설정 한 경우
Chathuranga 실바

경우 jobs_list.count == 0 {주어진 코드 위 // 추가} 다른 {self.tableView.backgroundView = 전무}
Chathuranga 실바

완전한. self.tableView.backgroundView = nil전에 내 if 문을 추가 하면 return jobs_list.count 잘 작동합니다. 감사
tylerSF

이 답변에서 첫 번째 솔루션을 사용하지 마십시오. 테이블보기 데이터 소스 메서드는 예상보다 더 많은 작업을 수행해서는 안됩니다. numberOfSections카운트를 반환해야합니다. 동일에 대한 numberOfRowsInSection. 언제든지 여러 번 호출 할 수 있습니다. 뷰를 업데이트하거나 데이터를 업데이트하거나 개수를 반환하는 것 외에는 아무것도하지 마십시오. 뷰 업데이트 논리는 이러한 메서드에 있어서는 안됩니다.
rmaddy

6

이 컨트롤을 사용해 볼 수 있습니다. 꽤 깔끔합니다. DZNEmptyDataSet

아니면 내가 너라면 내가 할 건

  • 데이터 배열이 비어 있는지 확인하십시오.
  • 비어 있으면 @ "No Data"라는 하나의 개체를 추가합니다.
  • cell.textLabel.text에 해당 문자열 표시

쉬워요


5

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
}

이 솔루션을 사용하지 마십시오. 테이블보기 데이터 소스 메서드는 예상보다 더 많은 작업을 수행해서는 안됩니다. numberOfSections카운트를 반환해야합니다. 동일에 대한 numberOfRowsInSection. 언제든지 여러 번 호출 할 수 있습니다. 뷰를 업데이트하거나 데이터를 업데이트하거나 개수를 반환하는 것 외에는 아무것도하지 마십시오. 뷰 업데이트 논리는 이러한 메서드에 있어서는 안됩니다.
rmaddy

나는 동의한다. 이 솔루션은 개선 될 수 있지만 사용할 수도 있습니다.
Teodor Ciuraru

이 솔루션을 사용해서는 안된다는 데 어떻게 동의하고 사용할 수 있다고 말할 수 있습니까? 그것은 모순입니다.
rmaddy

이 솔루션을 개선 할 수 있다는 데 동의하지만 현재 상태에서도 작동합니다.
Teodor Ciuraru 18.05.30

5

스위프트 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;
        }

이 솔루션을 사용하지 마십시오. 테이블보기 데이터 소스 메서드는 예상보다 더 많은 작업을 수행해서는 안됩니다. numberOfSections카운트를 반환해야합니다. 동일에 대한 numberOfRowsInSection. 언제든지 여러 번 호출 할 수 있습니다. 뷰를 업데이트하거나 데이터를 업데이트하거나 개수를 반환하는 것 외에는 아무것도하지 마십시오. 뷰 업데이트 논리는 이러한 메서드에 있어서는 안됩니다.
rmaddy

3

나는 당신의 문제를 해결하는 가장 우아한 방법은로 전환 생각 UITableViewControllerA를 UIViewController가 포함 UITableView. 이렇게 UIView하면 원하는 것을 기본보기의 하위보기로 추가 할 수 있습니다 .

이 작업을 수행하기 위해 UITableViewCell을 사용하는 것은 권장하지 않습니다. 앞으로 추가해야 할 사항이있을 수 있으며 상황이 빠르게 추악해질 수 있습니다.

이와 같은 작업을 수행 할 수도 있지만 이것이 최상의 솔루션은 아닙니다.

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

구현하는 가장 우아한 방법이며 항상 생각하는 좋은 방법 인 색상에 감사드립니다. 내 스토리 보드를 변경 UIViewController하여 UITableView.
SRMR

1
이것이 가장 미래를 보장하는 방법입니다. 나는 UITableViewController그것을 사용하는 것이 다른 방법으로하는 것보다별로 쉽지 않기 때문에 나는 나 자신을 사용한 적이 없다 . 그러나 그것은 당신의 미래 변화 능력을 제한한다.
Cihan Tek

반투명 막대가있는 경우 이는 미래 보장이 아닙니다. 나는 적극 권장합니다. 최소한 UITableViewController를 포함하고 적절하게 조정하는 UIViewController를 만드십시오.
xtravar

3

귀하의 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];
}

1
이 솔루션을 사용하지 마십시오. 테이블보기 데이터 소스 메서드는 예상보다 더 많은 작업을 수행해서는 안됩니다. numberOfSections카운트를 반환해야합니다. 동일에 대한 numberOfRowsInSection. 언제든지 여러 번 호출 할 수 있습니다. 뷰를 업데이트하거나 데이터를 업데이트하거나 개수를 반환하는 것 외에는 아무것도하지 마십시오. 뷰 업데이트 논리는 이러한 메서드에 있어서는 안됩니다.
rmaddy

2

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

2

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

위의 코드는 빈 셀이없는 테이블 뷰를 생성합니다.


2

나를 위해 일한 솔루션이 있습니다.

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

이것은 좋은 접근 방식입니다. 좀 더 둥글게 만들기 위해 다음과 같이 몇 가지 개선 사항을 추가했습니다. 1. tableview의 구분자 스타일을 캐시하고 비어 있거나 비어 있지 않은 상태 전환시이를 복원하여 다른 구분자 스타일이 필요한 사용 사례에이 하위 클래스를 적용 할 수 있도록합니다. 2. @IBInspectable var emptyStateText: String?이 클래스를 추가 하고 표시하면 @IBDesignable스토리 보드 또는 xib의 다른 장면에 대해 다른 빈 상태 텍스트를 변경할 수 있습니다. 즐겨! :)
Egist Li

1

tableview에 결과가없는 경우 원하는 모양과 메시지가있는 오버레이보기를 제공합니다. ViewDidAppear에서 할 수 있으므로 뷰를 표시하거나 표시하지 않기 전에 결과를 얻을 수 있습니다.


1

코드없이이 작업을 수행하려면 이것을 시도하십시오!

tableView를 클릭하십시오.

tableView 스크린 샷

스타일을 "일반"에서 "그룹화"로 변경하십시오.

테이블보기 속성 스크린 샷 -2

이제 사용하면 ....

tableView.backgroundView = 레이블 또는보기 삽입

구분 기호가 표시되지 않습니다!


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