Handling an empty UITableView. Print a friendly message

前端 未结 22 1056
青春惊慌失措
青春惊慌失措 2020-12-04 05:22

I have a UITableView that in some cases it is legal to be empty. So instead of showing the background image of the app, I would prefer to print a friendly message in the scr

相关标签:
22条回答
  • 2020-12-04 06:18

    Show Message for empty list, Wether its UITableView or 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
            }
        }
    }
    

    Usages:

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

    OR:

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

    Remember: Don't forget to remove the message label in case data will come after refresh.

    0 讨论(0)
  • 2020-12-04 06:18

    I made a few changes so that we don't need to check on the count manually, also i added constraints for the label so that nothing goes wrong no matter how large is the message as shown below:

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

    Usage

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            let message: String = "The list is empty."
            ticketsTableView.setEmptyMessage(message, tickets.isEmpty)
            return self.tickets.count
        }
    
    0 讨论(0)
  • 2020-12-04 06:20

    The easiest and quickest way to do this is to drag a label on to side panel under tableView. Create a outlet for the label and the tableView and add a if statement to hide and show the label and table as needed. Alternatively you can add tableView.tableFooterView = UIView(frame: CGRect.zero) this to you viewDidLoad() to give an empty table the perception that it is hidden if the table and background view have the same colour.

    0 讨论(0)
  • 2020-12-04 06:20

    Or alternatively you can use a bit customizable light-weight library

    SwiftEmptyState

    0 讨论(0)
提交回复
热议问题