একটি খালি ইউআইটিএবলভিউ পরিচালনা করছে। একটি বন্ধুত্বপূর্ণ বার্তা মুদ্রণ করুন


124

আমার একটি ইউআইটিএবলভিউ রয়েছে যে কোনও কোনও ক্ষেত্রে এটি খালি থাকা বৈধ। সুতরাং অ্যাপটির পটভূমি চিত্রটি দেখানোর পরিবর্তে আমি স্ক্রিনে একটি বন্ধুত্বপূর্ণ বার্তা মুদ্রণ করতে পছন্দ করব, যেমন:

এই তালিকাটি এখন খালি

এটি করার সহজ উপায় কী?


10
এই প্রকল্পটি দেখুন: github.com/dzenbot/DZNEmptyDataSet
oleynikd

@ ওলেনিকড আপনাকে ধন্যবাদ !!!!!
লুদা

উত্তর:


173

ইউআইটিএবলভিউর ব্যাকগ্রাউন্ডভিউ সম্পত্তিটি আপনার বন্ধু।

ইন viewDidLoadবা যে কোন জায়গায় আপনি reloadDataআপনি নির্ধারণ করা উচিত যদি আপনার টেবিল খালি থাকা অথবা না হয় এবং একটি UIView একটি UILabel সম্বলিত UITableView এর backgroundView সম্পত্তি আপডেট বা শুধু শূন্যে সেট করুন। এটাই.

ইউআইটিএবলভিউর ডেটা উত্সটি ডাবল ডিউটি ​​করা এবং একটি বিশেষ "তালিকা খালি রয়েছে" সেলটি অবশ্যই ফিরিয়ে আনা সম্ভব, এটি আমাকে ক্লডজ হিসাবে আঘাত করে। হঠাৎ করে numberOfRowsInSection:(NSInteger)sectionঅন্যান্য বিভাগের সারিগুলির সংখ্যা গণনা করতে হবে যে সেগুলি খালি রয়েছে কিনা তা নিশ্চিত করার বিষয়ে জিজ্ঞাসা করা হয়নি। আপনাকে একটি বিশেষ ঘর তৈরি করতে হবে যাতে খালি বার্তা রয়েছে। এছাড়াও ভুলে যাবেন না যে খালি বার্তাটি সামঞ্জস্য করার জন্য আপনাকে সম্ভবত আপনার ঘরের উচ্চতা পরিবর্তন করতে হবে। এটি সমস্ত করণীয় তবে ব্যান্ড-সহায়তা শীর্ষে এটি ব্যান্ড-এইডের মতো বলে মনে হয়।


12
ব্যাকগ্রাউন্ডভিউ সেরা সমাধান, আমি মনে করি। ধন্যবাদ!
ফেরান মেলিনচ

1
একটি অসুবিধা হ'ল টেবিল ভিউটি নীচে টানলে বার্তাটি তার অবস্থানে থেকে যায় on আমি আপডেটের অধীনে অ্যাপ স্টোর অ্যাপটিতে পছন্দ করতে চাই। এখানে খালি বার্তাটি স্ক্রোলিং আচরণের সাথে চলে ...
পরীক্ষায়

@ স্পষ্টতই যদি আপনার স্ক্রোল করার জন্য খালি বার্তাগুলির প্রয়োজন হয় তবে আপনি ব্যাকগ্রাউন্ড ভিউটি ব্যবহার করতে পারবেন না কারণ এটি স্ক্রোল শ্রেণিবদ্ধের অংশ নয়। আপনি সম্ভবত শূন্য অবস্থার জন্য একটি কাস্টম বিভাগ এবং ইউআইটিএবলভিউসেল ব্যবহার করতে চান।
লাইটনিংস্ট্রিক

টগল backgroundViewলুকানো সম্পত্তি যাওয়ার উপায়। সহ DZNEmptyDataSet, আমাদের এর ব্যবহার করতে হবেemptyDataSetSource
onmyway133

আপনি যদি বোতাম যুক্ত করতে চান তবে আপনার অবশ্যই তা করতে হবে: tableView.backgroundView!.userInteraction = trueআপনি যে লাইনটি সেট করেছেন তার পরে tableView.backgroundView = constructMyViewWithButtons()বা আপনি সেট করেছেন।
কেবিপন্টিয়াস

90

ঝনস্টনের উত্তর হিসাবে একই, তবে আমি এটিকে একটি এক্সটেনশন হিসাবে পছন্দ করেছি:

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
এক্সটেনশন আরও ভাল! ধন্যবাদ।
ওগলকান ওরহান

এক্সটেনশনটি ভালোবাসুন :)
অ্যালিক্স

1
আপনার যদি বিভাগগুলি থাকে, তবে আপনাকে এই যুক্তিটি func numberOfSections(in tableView: UITableView) -> Intপদ্ধতিতে স্থানান্তরিত করতে হবে
নৈপুণ্য

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/ এর সামান্য সহায়তায়


যদিও এটিতে চিত্র যুক্ত করতে চাই। তবে একটি দুর্দান্ত দ্রুত সমাধান।
অ্যানবিসউ

10
ক্লাসের পরিবর্তে একটি এক্সটেনশন ব্যবহার করুন (ভিউ কন্ট্রোলারটি পাস করবেন না)
সিজার

আমার পক্ষে কাজ করার জন্য আমি উপরের কোডটি পেতে সক্ষম হয়েছি না, তবে আমি এই উত্তরে কোডটি (প্রথম এক) কাজ করতে সক্ষম হয়েছি, অন্যদের ক্ষেত্রেও একই সমস্যা আছে। এছাড়াও আমি মনে করি ২ য় উত্তরটিও
রেনি ওলসন

viewController.tableView.separatorStyle = .noneপ্রয়োজন হয় না।
দিমিত্রি

17

আমি নিম্নলিখিত গ্রন্থাগারটি সুপারিশ করছি: DZNEmptyDataSet

আপনার প্রকল্পে এটি যুক্ত করার সবচেয়ে সহজ উপায় হ'ল এটি কোকোপডগুলির সাথে এটি ব্যবহার করা: pod 'DZNEmptyDataSet'

আপনার টেবিলভিউ নিয়ন্ত্রণকারীটিতে নিম্নলিখিত আমদানি বিবৃতি (সুইফট) যুক্ত করুন:

import DZNEmptyDataSet

তারপর নিশ্চিত আপনার বর্গ কে কনর্ফাম করে করতে DNZEmptyDataSetSourceএবং DZNEmptyDataSetDelegateযেমন:

class MyTableViewController: UITableViewController, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate

আপনার viewDidLoadকোডে নিম্নলিখিত লাইনগুলি যুক্ত করুন:

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

খালি স্টেটটি দেখানোর জন্য আপনাকে যা করতে হবে তা হ'ল:

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

এই পদ্ধতিগুলি বাধ্যতামূলক নয়, কেবল কোনও বোতাম ইত্যাদি ছাড়াই খালি অবস্থা প্রদর্শন করাও সম্ভব

সুইফট 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হ'ল সারিগুলির সংখ্যা শূন্য হলে আপনার ডেটা উত্সকে পরিবর্তন করতে হবে এবং পদ্ধতিতে একটি বিশেষ-উদ্দেশ্য সেল (সম্ভবত কোনও আলাদা ঘর সনাক্তকারী সহ) উত্পাদন করা হবে 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
Table numRows - ows rowsDeleted এর ফলাফলটির সাথে মিলের প্রয়োজন deleteRowsAtIndexPaths:withRowAnimation:অনুসারে সংখ্যাটি ফিরে আসার সাথে সাথে সারিগুলি মুছে ফেলা সারণীগুলির সাহায্যে আমার সমস্যা হয়েছে numberOfRowsInSection
প্রাণী 451

4
আমি অত্যন্ত, এর বিরুদ্ধে অত্যন্ত পরামর্শ দিচ্ছি। এটি আপনার কোডগুলিকে প্রান্তের মামলাগুলির সাথে ধাঁধা দেয়।
অক্স্রভর

2
@xtravar ডাউনভোটিংয়ের পরিবর্তে নিজের উত্তর পোস্ট করার বিষয়টি বিবেচনা করুন।
dasblinkenlight

1
আমি সেই পথে নেমে এসেছি এবং এটি তার নিজস্ব অ্যারেগুলিতে নিয়ে যায়। আমার অভিজ্ঞতা হিসাবে, অ্যাপল এপিআইগুলি প্রতিস্থাপনের চেষ্টা করার চেয়ে উন্নত করা প্রায় সর্বদা ভাল।
xtravar

1
এই সমাধানটি NSFetchedResultsController এর সাথে কাজ করবে না। আমি এর পরিবর্তে ব্যাকগ্রাউন্ডভিউ পদ্ধতির চেষ্টা করে যাচ্ছি।
স্যাম

10

আমি এটির জন্য ফোর্ডফুটারআইএনএসেকশন বার্তাটি ব্যবহার করছি। আমি জানি না এটি suboptimal কিনা বা না, তবে এটি কাজ করে।

-(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
ট্রুম্যান 1

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

আমি কেবলমাত্র ঘরগুলির পরে টেবিলভিউয়ের মধ্যে একটি ইউআইটিএক্সেক্সটভিউটি টেনে আনার এবং ছাড়ার পরামর্শ দিতে পারি। ভিউকন্ট্রোলারের সাথে সংযোগ স্থাপন করুন এবং উপযুক্ত হলে এটি লুকান / প্রদর্শন করুন (যেমন যখনই টেবিলটি পুনরায় লোড হয়)।

এখানে চিত্র বর্ণনা লিখুন


এটাই সহজতম উপায়)!
মুনভ্যাডার

এ জাতীয় বেদনাদায়ক মাথাব্যথা আপেল উপায়ে; এই ধারণার জন্য ধন্যবাদ
Eenvincible

5

ব্যাকগ্রাউন্ডভিউটি ব্যবহার করা ভাল, তবে এটি মেল.এ্যাপের মতো সুন্দরভাবে স্ক্রোল করে না।

অষ্টাভর যা করেছে তার মতোই আমি কিছু করেছি।

এর ভিউ হায়ারার্কির বাইরে আমি একটি ভিউ যুক্ত করেছি 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এবং এটি মাপসই করা হয়েছে তা নিশ্চিত করে
হ্যানেল

4

অ্যাপল অনুসারে এটি করার সঠিক পন্থা কনটেইনার ভিউ কন্ট্রোলার ব্যবহার করা

আমি আমার খালি স্থিতির সমস্ত দৃশ্য পৃথক স্টোরিবোর্ডে রেখেছি। এর নিজস্ব প্রতিটি ইউআইভিউকন্ট্রোলার সাবক্লাসের নীচে। আমি সরাসরি তাদের মূল দৃষ্টিতে সামগ্রী যুক্ত করি add যদি কোনও ক্রিয়া / বোতামের প্রয়োজন হয় তবে এটি হ্যান্ডেল করার জন্য আপনার কাছে ইতিমধ্যে একটি নিয়ামক রয়েছে।
তারপরে Story স্টোরিবোর্ড থেকে কাঙ্ক্ষিত ভিউ কন্ট্রোলারকে ইনস্ট্যান্ট করার এটি কেবলমাত্র শিশু ভিউ নিয়ন্ত্রক হিসাবে যুক্ত করুন এবং কন্টেইনার ভিউটিকে টেবিলভিউয়ের শ্রেণিবিন্যাসে (সাব ভিউ) যুক্ত করুন। আপনার খালি স্থিতির দৃশ্যটিও স্ক্রোলযোগ্য হবে যা ভাল লাগে এবং আপনাকে রিফ্রেশ করার জন্য টান প্রয়োগ করতে দেয়।

অধ্যায়টি পড়ুন 'আপনার সামগ্রীতে চাইল্ড ভিউ কন্ট্রোলার যুক্ত করা'কীভাবে প্রয়োগ করতে হয় তার জন্য সহায়তার জন্য ।

কেবলমাত্র নিশ্চিত করুন যে আপনি সন্তানের দৃশ্যের ফ্রেমটি সেট করেছেন (0, 0, tableView.frame.width, tableView.frame.height)এবং জিনিসগুলি কেন্দ্রিকভাবে এবং সঠিকভাবে সাজানো হবে।


3

প্রথমত, অন্যান্য জনপ্রিয় পদ্ধতির সাথে সমস্যাগুলি।

BackgroundView

আপনি যদি এটি ইউইলবেল হিসাবে সেট করার সাধারণ কেসটি ব্যবহার করেন তবে পটভূমির দৃশ্যটি ভালভাবে কেন্দ্র করে না।

বার্তাটি প্রদর্শনের জন্য ঘর, শিরোনাম বা পাদচরণ

এটি আপনার ক্রিয়ামূলক কোডে হস্তক্ষেপ করে এবং অদ্ভুত প্রান্তের কেসগুলি প্রবর্তন করে। আপনি যদি আপনার বার্তাটিকে পুরোপুরি কেন্দ্র করে নিতে চান তবে এটি জটিলতার আরও একটি স্তর যুক্ত করে।

আপনার নিজস্ব টেবিল ভিউ নিয়ন্ত্রণকারী রোলিং

আপনি রিফ্রেশকন্ট্রোলের মতো অন্তর্নির্মিত কার্যকারিতা হারাবেন এবং চাকাটি পুনরায় আবিষ্কার করুন। সেরা রক্ষণাবেক্ষণযোগ্য ফলাফলের জন্য ইউআইটিএবলভিউ নিয়ন্ত্রণকারীকে আটকে দিন।

চাইল্ড ভিউ কন্ট্রোলার হিসাবে ইউআইটিএবলভিউ কনট্রোলার যুক্ত করা হচ্ছে

আমার একটি অনুভূতি রয়েছে যে আপনি আইওএস +++ এ অন্তর্ভুক্ত বিষয়বস্তুগুলি অন্তর্ভুক্ত করবেন - আরও কেন জটিল জিনিস?

আমার সমাধান

আমি যে সেরা সমাধানটি নিয়ে এসেছি (এবং মঞ্জুর করা হয়েছে এটি আদর্শ নয়) হ'ল একটি বিশেষ দৃষ্টিভঙ্গি তৈরি করা যা কোনও স্ক্রোল ভিউয়ের শীর্ষে বসতে পারে এবং সে অনুযায়ী কাজ করতে পারে। এটি স্পষ্টতই আইওএস 7-এ জটিল বিষয়বস্তুতে ইনসেট পাগলামির সাথে জটিল হয়ে ওঠে, তবে এটি কার্যক্ষম।

আপনার জন্য যে বিষয়গুলি লক্ষ্য রাখতে হবে:

  • রিলোডলোডের সময় কোনও সময়ে টেবিল বিভাজককারীদের সামনে আনা হয় - আপনাকে এ থেকে রক্ষা করা দরকার
  • কন্টেন্টআইসেট / কন্টেন্টঅফসেট - আপনার বিশেষ দৃশ্যে এই কীগুলি পর্যবেক্ষণ করুন
  • কীবোর্ড - আপনি যদি কীবোর্ডটি যাতে না চান তবে এটি অন্য একটি গণনা
  • অটোলেআউট - আপনার ভিউ অবস্থানের জন্য ফ্রেম পরিবর্তনের উপর নির্ভর করতে পারবেন না

একবার একবার কোনও ইউআইভিউ সাবক্লাসে এটি বের হয়ে গেলে আপনি এটিকে সমস্ত কিছুর জন্য ব্যবহার করতে পারেন - স্পিনার লোড করা, দর্শন অক্ষম করা, ত্রুটির বার্তা প্রদর্শন ইত্যাদি showing


আপনি কি আপনার উত্তরে বিস্তারিত বলতে পারেন? টেবিলটি খালি থাকলে কীভাবে বলবেন? তারপরে "সেই অনুযায়ী কাজ করুন"।
মাইকেল ওজারিয়ানস্কি

আপনি জানেন যে আপনার টেবিলটি খালি রয়েছে কারণ আপনি নিজের টেবিলে জনবহুল। সুতরাং আপনার ভিউ কন্ট্রোলারে আপনার অ্যাসিক্রোনাস লোডিং কলব্যাক হবে। সেই কলব্যাকে, যদি (আইটেমস টোশো কোড == 0) {আপনার ভিউটি স্ক্রোল ভিউতে যুক্ত করুন} কৌতুকপূর্ণ অংশটি সেই শীর্ষ দৃশ্যটি ('ঝাল / বার্তা ভিউ') তৈরি করছে যাতে স্ক্রোল ভিউ, মাইনাস কনটেন্টইনসেট ইত্যাদির পুরো ফ্রেমটি ধরে রাখতে পারে, যাতে বার্তাটি উল্লম্বভাবে কেন্দ্রীভূত হয়।
xtrapar

আপনি কীভাবে টেবিল দৃশ্যের উপরে একটি দৃশ্য যুক্ত করবেন? সেলফ ভিউ হ'ল টেবিল ভিউ এবং আমি যদি addSubViewএটি ব্যবহার করি তবে এটি টেবিল দৃশ্যের সাথে সংযুক্ত যা যা সর্বদা স্বয়ংক্রিয় বিন্যাসে সমস্যা তৈরি করে।
পরীক্ষার

আপনি টেবিল দৃশ্যের মধ্যে যে ভিউটি রেখেছেন তাতে অটোলেআউট ব্যবহার করা উচিত নয় এবং টেবিলভিউ নিজেই অটোলেআউট ব্যবহার করে না।
xtravar

1
আপনি সেখানে একটি পদ্ধতির হাতছাড়া করেছেন; আপনি একটি ইউআইটিএবল ভিউ কনট্রোলার ব্যবহার করতে পারেন এবং এটি নিয়মিত
ইউআইভিউ

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

খালি তালিকার জন্য বার্তাটি দেখান, এর ইউআইটিএবলভিউ বা ইউআইকোলিকেশনভিউয়ের চেয়ে বেশি

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
আমি যদি একটি শর্ত যুক্ত করি তবে ম্যাসেজের হিসাব! = 0 {দেখান}
এডডউইন পাজ

1

স্টোরিবোর্ডে আপনার টেবিলভিউ নিয়ন্ত্রণকারী দৃশ্য নির্বাচন করুন Select

এখানে চিত্র বর্ণনা লিখুন

আপনার বার্তা সহ ইউআইভিউ ভিউ লেবেলটি টানুন এবং ছেড়ে দিন (উদা: ডেটা নেই)

এখানে চিত্র বর্ণনা লিখুন

আপনার টেবিলভিউ কনট্রোলারের উপর ইউআইভিউয়ের আউটলেট তৈরি করুন (যেমন আপনার নোনাডাটাভিউ হিসাবে বলুন)।

এবং ভিডিডলিডে

স্ব.ট্যাবলভিউ.ব্যাকগ্রাউন্ডভিউ = আপনার নোটাটাভিউ


1

সুইফট 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

আপনি এটি আপনার বেস শ্রেণিতে যুক্ত করতে পারেন।

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

এপিআই থেকে ডেটা পাওয়ার বিষয়ে ক্লাসে এটি এর মতো দেখান।

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

আরে @ মুদাসসির-আসগর হাইডনোডাটা ম্যাসেজ ফাংশনটি কেমন দেখাচ্ছে?
সমর

1
হাই, @ সামের আমি উপরের উত্তরটি সবেমাত্র আপডেট করেছি। এটি দেখানোর জন্য ধন্যবাদ, আশা করি এটি সাহায্য করবে :)
মুদাসাসির আসগর

0

সুইফ্ট সংস্করণ তবে আরও ভাল এবং সহজ ফর্ম। ** 3.0

আমি আশা করি এটি আপনার উদ্দেশ্য ......

আপনার ইউআইটিএবলভিউ নিয়ন্ত্রণকারী In

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

আপনি চাইলে গণনা = 0 হলে লেবেলটি খালি চিত্রদর্শন দিয়েও প্রতিস্থাপন করতে পারেন ..
Zach

0

এটি করার সবচেয়ে সহজ এবং দ্রুততম উপায় হ'ল টেবিলভিউয়ের নীচে পাশের প্যানেলে একটি লেবেল টেনে আনতে। লেবেল এবং টেবিলভিউয়ের জন্য একটি আউটলেট তৈরি করুন এবং প্রয়োজন অনুসারে লেবেল এবং টেবিলটি লুকিয়ে রাখতে এবং প্রদর্শন করতে একটি বিবৃতি যুক্ত করুন। বিকল্পভাবে আপনি টেবিল ভিউ.ট্যাবলফুটারভিউ = ইউআইভিউ (ফ্রেম: সিজিআরেক্ট.জারো) এটি আপনার কাছে ভিডডিডলয়েড () যুক্ত করতে পারেন টেবিল এবং পটভূমির দৃশ্যের একই রঙ থাকলে এটি লুকিয়ে রয়েছে এই উপলব্ধিটি hidden


(এই পোস্টটি প্রশ্নের কোনও মানের উত্তর দেয় বলে মনে হচ্ছে না Please দয়া করে হয় আপনার উত্তরটি সম্পাদনা করুন এবং আরও বিশদ তথ্য সহ এটি সম্পূর্ণ করুন, বা কেবল প্রশ্নের মন্তব্যে এটি পোস্ট করুন)।
সুনুন ןɐ কিউপি

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.