ฉันมี UITableView ซึ่งในบางกรณีมันถูกกฎหมายที่จะว่างเปล่า ดังนั้นแทนที่จะแสดงภาพพื้นหลังของแอปฉันต้องการพิมพ์ข้อความที่เป็นมิตรในหน้าจอเช่น:
รายการนี้ว่างเปล่า
วิธีที่ง่ายที่สุดในการทำคืออะไร?
ฉันมี UITableView ซึ่งในบางกรณีมันถูกกฎหมายที่จะว่างเปล่า ดังนั้นแทนที่จะแสดงภาพพื้นหลังของแอปฉันต้องการพิมพ์ข้อความที่เป็นมิตรในหน้าจอเช่น:
รายการนี้ว่างเปล่า
วิธีที่ง่ายที่สุดในการทำคืออะไร?
คำตอบ:
คุณสมบัติ backgroundView ของ UITableView คือเพื่อนของคุณ
ในviewDidLoad
หรือที่ใดก็ได้ที่คุณreloadData
ควรพิจารณาว่าตารางของคุณว่างหรือไม่และอัปเดตคุณสมบัติ backgroundView ของ UITableView ด้วย UIView ที่มี UILabel หรือเพียงแค่ตั้งค่าเป็นศูนย์ แค่นั้นแหละ.
แน่นอนว่าเป็นไปได้ที่จะทำให้แหล่งข้อมูลของ UITableView ทำหน้าที่สองครั้งและส่งคืนเซลล์พิเศษ "list is empty" มันทำให้ฉันกลายเป็นกากตะกอน ทันใดนั้นnumberOfRowsInSection:(NSInteger)section
ต้องคำนวณจำนวนแถวของส่วนอื่น ๆ ที่ไม่ได้ถามเพื่อให้แน่ใจว่าว่างเกินไป คุณต้องสร้างเซลล์พิเศษที่มีข้อความว่าง อย่าลืมว่าคุณอาจต้องเปลี่ยนความสูงของเซลล์เพื่อรองรับข้อความว่าง ทั้งหมดนี้ทำได้ แต่ดูเหมือนว่า band-aid จะอยู่ด้านบนของ band-aid
backgroundView
คุณสมบัติที่ซ่อนอยู่เป็นวิธีที่จะไป ด้วยDZNEmptyDataSet
เราต้องใช้มันemptyDataSetSource
tableView.backgroundView!.userInteraction = true
หลังบรรทัดที่คุณกำหนดtableView.backgroundView = constructMyViewWithButtons()
หรือตามที่คุณตั้งไว้
เหมือนกับคำตอบของ 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
}
func numberOfSections(in tableView: UITableView) -> Int
วิธีการ
จากคำตอบที่นี่นี่คือคลาสสั้น ๆ ที่ฉันสร้างขึ้นซึ่งคุณสามารถใช้ใน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/
viewController.tableView.separatorStyle = .none
ไม่จำเป็น
ฉันขอแนะนำไลบรารีต่อไปนี้: DZNEmptyDataSet
วิธีที่ง่ายที่สุดในการเพิ่มในโครงการของคุณคือใช้กับ Cocaopods ดังนี้: pod 'DZNEmptyDataSet'
ใน TableViewController ของคุณเพิ่มคำสั่งนำเข้าต่อไปนี้ (Swift):
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)
}
วิธีการเหล่านี้ไม่ได้บังคับ แต่ยังสามารถแสดงสถานะว่างเปล่าโดยไม่มีปุ่มเป็นต้น
สำหรับ 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)
}
วิธีหนึ่งในการทำเช่นนี้คือการแก้ไขแหล่งข้อมูลของคุณเพื่อส่งคืน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
ที่ได้รับการกำหนดค่าด้วยข้อความที่เหมาะสม
deleteRowsAtIndexPaths:withRowAnimation:
เนื่องจากจำนวนที่ส่งคืนจากnumberOfRowsInSection
ความต้องการตรงกับผลลัพธ์ของ $ numRows - $ rowDeleted
ฉันใช้ข้อความ 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;
}
return tableView.numberOfRowsInSection(section) == 0 ? "This list is now empty" : nil
ดังนั้นเพื่อความปลอดภัยยิ่งขึ้น:
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
}
}
ฉันสามารถแนะนำให้ลากและวาง UITextView ภายใน TableView หลังเซลล์เท่านั้น ทำการเชื่อมต่อกับ ViewController และซ่อน / แสดงตามความเหมาะสม (เช่นเมื่อใดก็ตามที่ตารางโหลดซ้ำ)
การใช้ backgroundView นั้นใช้ได้ แต่มันไม่ได้เลื่อนอย่างสวยงามเหมือนใน Mail.app
ฉันทำสิ่งที่คล้ายกับสิ่งที่xtravarทำ
ฉันเพิ่มมุมมองภายนอกลำดับชั้นมุมมองของไฟล์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
และให้แน่ใจว่ามันจะปรับขนาดพอดี
การใช้ Container View Controller เป็นวิธีที่ถูกต้องตามที่Appleกำหนด
ฉันใส่มุมมองสถานะว่างเปล่าทั้งหมดไว้ในสตอรี่บอร์ดแยกต่างหาก แต่ละอันอยู่ภายใต้คลาสย่อย UIViewController ของตัวเอง ฉันเพิ่มเนื้อหาโดยตรงภายใต้มุมมองรูท หากจำเป็นต้องดำเนินการ / ปุ่มใด ๆ ตอนนี้คุณมีตัวควบคุมที่จะจัดการแล้ว
จากนั้นเป็นเพียงเรื่องของการสร้างอินสแตนซ์ตัวควบคุมมุมมองที่ต้องการจาก Storyboard นั้นเพิ่มเป็นตัวควบคุมมุมมองเด็กและเพิ่มมุมมองคอนเทนเนอร์ไปยังลำดับชั้นของ tableView (มุมมองย่อย) มุมมองสถานะว่างของคุณจะเลื่อนได้เช่นกันซึ่งให้ความรู้สึกดีและช่วยให้คุณสามารถใช้การดึงเพื่อรีเฟรชได้
อ่านบท'การเพิ่มตัวควบคุมมุมมองเด็กในเนื้อหาของคุณ'เพื่อขอความช่วยเหลือเกี่ยวกับวิธีการนำไปใช้
ตรวจสอบให้แน่ใจว่าคุณตั้งค่ากรอบมุมมองเด็กเป็น
(0, 0, tableView.frame.width, tableView.frame.height)
และสิ่งต่างๆจะอยู่กึ่งกลางและจัดตำแหน่งอย่างเหมาะสม
ประการแรกปัญหาเกี่ยวกับแนวทางยอดนิยมอื่น ๆ
BackgroundView
มุมมองพื้นหลังไม่ได้อยู่ตรงกลางหากคุณใช้กรณีง่ายๆในการตั้งค่าให้เป็น UILabel
เซลล์ส่วนหัวหรือส่วนท้ายเพื่อแสดงข้อความ
สิ่งนี้รบกวนรหัสการทำงานของคุณและแนะนำกรณีขอบแปลก ๆ หากคุณต้องการจัดกึ่งกลางข้อความของคุณอย่างสมบูรณ์แบบนั่นจะเพิ่มความซับซ้อนอีกระดับ
หมุนตัวควบคุมมุมมองตารางของคุณเอง
คุณสูญเสียฟังก์ชันการทำงานในตัวเช่น refreshControl และสร้างวงล้อใหม่ ยึดติดกับ UITableViewController เพื่อผลลัพธ์ที่ดีที่สุดในการบำรุงรักษา
การเพิ่ม UITableViewController เป็นตัวควบคุมมุมมองเด็ก
ฉันรู้สึกว่าคุณจะพบกับปัญหา contentInset ใน iOS 7+ - ทำไมสิ่งต่าง ๆ จึงซับซ้อน?
ทางออกของฉัน
ทางออกที่ดีที่สุดที่ฉันคิดขึ้นมา (และไม่เหมาะอย่างยิ่ง) คือการสร้างมุมมองพิเศษที่สามารถนั่งอยู่ด้านบนของมุมมองแบบเลื่อนและดำเนินการตามนั้น เห็นได้ชัดว่าสิ่งนี้มีความซับซ้อนใน iOS 7 ด้วย contentInset madness แต่ก็ทำได้
สิ่งที่คุณต้องระวัง:
เมื่อคุณพบสิ่งนี้หนึ่งครั้งในคลาสย่อย UIView หนึ่งแล้วคุณสามารถใช้มันได้ทุกอย่างไม่ว่าจะเป็นการโหลดสปินเนอร์การปิดการใช้งานมุมมองการแสดงข้อความแสดงข้อผิดพลาด ฯลฯ
addSubView
มันแนบกับมุมมองตารางซึ่งมักทำให้เกิดปัญหากับการจัดวางอัตโนมัติ
นี่เป็นทางออกที่ง่ายและดีที่สุด
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;
แสดงข้อความสำหรับรายการที่ว่างเปล่า, อากาศของ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!")
}
ข้อควรจำ: อย่าลืมลบป้ายข้อความในกรณีที่ข้อมูลจะมาหลังจากรีเฟรช
เลือกฉากควบคุมตารางของคุณในสตอรีบอร์ด
ลากและวาง UIView เพิ่มป้ายกำกับด้วยข้อความของคุณ (เช่น: ไม่มีข้อมูล)
สร้างทางออกของ UIView (เช่น yournoDataView) บน TableViewController ของคุณ
และใน viewDidLoad
self.tableView.backgroundView = yourNoDataView
ใช้ 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
}
คุณสามารถเพิ่มสิ่งนี้ลงในคลาสพื้นฐานของคุณ
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()
}
เวอร์ชัน Swift แต่รูปแบบที่ดีกว่าและเรียบง่ายกว่า ** 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
}
}
}
Helper Class พร้อมฟังก์ชั่น:
/* 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 ฉันก็กำหนดข้อความให้ ค่อนข้างง่ายและบรรลุสิ่งที่คุณพยายามทำด้วยโค้ดไม่กี่บรรทัด
ฉันมีสองส่วนในตารางของฉัน (งานและโรงเรียน)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (jobs.count == 0 && schools.count == 0) {
emptyLbl.text = "No jobs or schools"
} else {
emptyLbl.text = ""
}
วิธีที่ง่ายและรวดเร็วที่สุดคือลากป้ายไปที่แผงด้านข้างใต้ tableView สร้างเต้ารับสำหรับเลเบลและ tableView และเพิ่มคำสั่ง if เพื่อซ่อนและแสดงเลเบลและตารางตามต้องการ หรือคุณสามารถเพิ่ม tableView.tableFooterView = UIView (frame: CGRect.zero) ให้กับคุณ viewDidLoad () เพื่อให้ตารางว่างรับรู้ว่ามันถูกซ่อนไว้หากมุมมองตารางและพื้นหลังมีสีเดียวกัน
ฉันทำการเปลี่ยนแปลงเล็กน้อยเพื่อที่เราจะได้ไม่ต้องตรวจสอบการนับด้วยตนเองและฉันได้เพิ่มข้อ จำกัด สำหรับป้ายกำกับเพื่อไม่ให้มีอะไรผิดพลาดไม่ว่าข้อความจะใหญ่แค่ไหนตามที่แสดงด้านล่าง:
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
}
หรือคุณสามารถใช้ไลบรารีน้ำหนักเบาที่ปรับแต่งได้เล็กน้อย