英文:
Tableview cells do not show the detailTextLabel
问题
在我的UITableView中显示次要数据存在问题。我从API获取3条数据:名称、地址、电话。显示“名称”没有问题,但当我尝试显示次要数据(地址、电话)时遇到问题。我有两个代码文件,一个是处理TableView的ViewController文件,另一个是处理数据解析的Model文件。代码中将次要数据称为"detailedTextLabel"。非常感谢任何帮助!
第一个代码文件是ViewController - 第二个是Model文件。
import UIKit
struct SportsItem {
let facility: String
let address: String
let telephone: String
}
class SportsResultsViewController: UIViewController, UITableViewDataSource {
var sportsData: [SportsItem] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sportsData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath)
cell.textLabel?.text = sportsData[indexPath.row].facility
cell.detailTextLabel?.numberOfLines = 0
cell.detailTextLabel?.text = "Address: \(sportsData[indexPath.row].address)\nPhone: \(sportsData[indexPath.row].telephone)"
cell.textLabel?.font = UIFont.systemFont(ofSize: 8)
cell.detailTextLabel?.font = UIFont.systemFont(ofSize: 8)
return cell
}
var jsonString: String?
override func viewDidLoad() {
super.viewDidLoad()
resultsTableView.dataSource = self
resultsTableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
resultsTableView.cellLayoutMarginsFollowReadableWidth = true
resultsTableView.rowHeight = UITableView.automaticDimension
resultsTableView.estimatedRowHeight = 164.0
if let jsonString = jsonString {
if let data = jsonString.data(using: .utf8),
let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let features = json["features"] as? [[String: Any]] {
var sportsData: [SportsItem] = []
for i in 0..<min(10, features.count) {
if let feature = features[i]["properties"] as? [String: Any] ?? [:],
let address = feature["Address"] as? String,
let telephone = feature["Telephone"] as? String,
let facility = feature["Facility Name"] as? String {
let sportsItem = SportsItem(facility: facility, address: address, telephone: telephone)
sportsData.append(sportsItem)
}
}
self.sportsData = sportsData
if sportsData.isEmpty {
// 处理空数据情况(如果需要)
}
resultsTableView.reloadData()
}
}
}
@IBAction func findHotelsPressed(_ sender: UIButton) {
UIApplication.shared.open(URL(string: "https://www.hotels.com/de606379/hotels-hong-kong-hong-kong-sar/")!)
}
@IBOutlet weak var resultsTableView: UITableView!
}
第二个代码文件(DataModel文件):
import UIKit
struct SportsManager {
let sportsURL = "https://geodata.gov.hk/gs/api/v1.0.0/geoDataQuery?q=%7Bv%3A%221%2E0%2E0%22%2Cid%3A%22d1a2e8e0-8636-41e9-b664-0e64b86860a2%22%2Clang%3A%22ALL%22%7D"
func getSportsData(completion: @escaping (String?) -> Void) {
guard let url = URL(string: sportsURL) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
print(error.localizedDescription)
completion(nil)
return
}
guard let data = data else {
completion(nil)
return
}
do {
let jsonData = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
let jsonString = try JSONSerialization.data(withJSONObject: jsonData ?? "", options: .prettyPrinted)
let sportsData = String(data: jsonString, encoding: .utf8)
completion(sportsData)
} catch let error {
print(error.localizedDescription)
completion(nil)
}
}.resume()
}
}
地址行不会显示在表格单元中。
英文:
Issue getting secondary data to display in my UITableView. I have 3 pieces of data coming back from the API - Name, Address, Telephone. No issues getting "Name" to display, but when I try to display the secondary data (address, telephone) I am stuck. I have two code files here, a ViewController File that is handling the TableView and a Model file that handles the data parsing. The secondary data is referred to as "detailedTextLabel" in my code. Any help greatly appreciated!
First Code File is ViewController - Second is Model file.
import UIKit
struct SportsItem {
let facility: String
let address: String
let telephone: String
}
class SportsResultsViewController: UIViewController, UITableViewDataSource {
var sportsData: [SportsItem] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sportsData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath)
cell.textLabel?.text = sportsData[indexPath.row].facility
cell.detailTextLabel?.numberOfLines = 0
cell.detailTextLabel?.text = "Address: \(sportsData[indexPath.row].address)\nPhone: \(sportsData[indexPath.row].telephone)"
cell.textLabel?.font = UIFont.systemFont(ofSize: 8)
cell.detailTextLabel?.font = UIFont.systemFont(ofSize: 8)
return cell
}
var jsonString: String?
override func viewDidLoad() {
super.viewDidLoad()
resultsTableView.dataSource = self
resultsTableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
resultsTableView.cellLayoutMarginsFollowReadableWidth = true
resultsTableView.rowHeight = UITableView.automaticDimension
resultsTableView.estimatedRowHeight = 164.0
if let jsonString = jsonString {
if let data = jsonString.data(using: .utf8),
let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let features = json["features"] as? [[String: Any]] {
var sportsData: [SportsItem] = []
for i in 0..<min(10, features.count) {
if let feature = features[i]["properties"] as? [String: Any]? ?? [:],
let address = feature["Address"] as? String,
let telephone = feature["Telephone"] as? String,
let facility = feature["Facility Name"] as? String {
let sportsItem = SportsItem(facility: facility, address: address, telephone: telephone)
sportsData.append(sportsItem)
}
}
self.sportsData = sportsData
if sportsData.isEmpty {
// Handle empty data case if needed
}
resultsTableView.reloadData()
}
}
}
@IBAction func findHotelsPressed(_ sender: UIButton) {
UIApplication.shared.open(URL(string: "https://www.hotels.com/de606379/hotels-hong-kong-hong-kong-sar/")!)
}
@IBOutlet weak var resultsTableView: UITableView!
}
Second Code File (DataModel File)...
import UIKit
struct SportsManager {
let sportsURL = "https://geodata.gov.hk/gs/api/v1.0.0/geoDataQuery?q=%7Bv%3A%221%2E0%2E0%22%2Cid%3A%22d1a2e8e0-8636-41e9-b664-0e64b86860a2%22%2Clang%3A%22ALL%22%7D"
func getSportsData(completion: @escaping (String?) -> Void) {
guard let url = URL(string: sportsURL) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
print(error.localizedDescription)
completion(nil)
return
}
guard let data = data else {
completion(nil)
return
}
do {
let jsonData = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
let jsonString = try JSONSerialization.data(withJSONObject: jsonData ?? "", options: .prettyPrinted)
let sportsData = String(data: jsonString, encoding: .utf8)
completion(sportsData)
} catch let error {
print(error.localizedDescription)
completion(nil)
}
}.resume()
}
}
The address line doesn't appear in the table cells:
答案1
得分: 1
问题在于,只有在使用样式.default
之外的样式创建单元格时,单元格的detailTextLabel
才有效。在您的情况下,您希望使用样式.subtitle
创建单元格。
您有两种可能的解决方案。一种是修复您的代码,另一种是正确更新您的故事板。
仅代码部分:
-
删除以下行:
resultsTableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
-
将以下行:
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath)
替换为以下行:
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) ?? UITableViewCell(style: .subtitle, reuseIdentifier: "CellIdentifier")
就这样。现在,您应该在每个单元格中看到两行文本。
故事板部分:
由于您已经在故事板中创建了表视图(基于它作为输出),因此您真的应该在故事板中完成所有的表和单元格设置。通过故事板连接表的数据源和代理输出。在故事板中设置原型单元格。在您的情况下,将单元格的样式设置为“Subtitle”并将标识符设置为“CellIdentifier”。
还要注意,自iOS 14以来,使用textLabel
和detailTextLabel
进行旧样式的表格单元格设置已被弃用。除非需要支持iOS 13,否则您应该要么创建自己的自定义单元格以获取所需的内容,要么使用新的内容配置API。
英文:
The problem is that a cell's detailTextLabel
is only valid if the cell is created with a style other than .default
. In your case you want cells to be created with a style of .subtitle
.
You have two possible solutions. One is to fix your code, the other is to update your storyboard correctly.
Code-only:
-
Remove the line:
resultsTableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
-
Replace the line:
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath)
with the line:
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) ?? UITableViewCell(style: .subtitle, reuseIdentifier: "CellIdentifier")
That's it. You should now see both lines of text in each cell.
Storyboard:
Since you have created the table view in a storyboard (based on it being an outlet), you really should do all of the table and cell setup in the storyboard. It makes little sense to add the table view via storyboard and outlet but then use code to set it up. Connect the table's data source and delegate outlets in the storyboard. Setup the prototype cell in the storyboard. In your case, set the cell's Style to "Subtitle" and set the Identifier to "CellIdentifier".
Also note that the old style table cell setup using textLabel
and detailTextLabel
has been deprecated since iOS 14. Unless you need to support iOS 13, you should be either creating your own custom cell with the desired content or use the new content configuration APIs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论