UiTableView cellForRowAt 没有返回好的值并且不能滚动
Posted
技术标签:
【中文标题】UiTableView cellForRowAt 没有返回好的值并且不能滚动【英文标题】:UiTableView cellForRowAt not return good value and can't scroll 【发布时间】:2017-09-18 22:49:18 【问题描述】:我是 swift 和 UITableView 的新手,我正在从请求中获取数据,并试图在表格视图上显示结果。 我得到的数据很好,但我的表格视图没有滚动。我知道这个问题有很多问题,但我看到其他人的答案,我无法解决我的问题,有虚拟代码:
@IBOutlet weak var tav: UITableView!
//Emoji array dynamically created
var emojisArray: [Emoji] = []
didSet
tav.reloadData()
override func viewDidLoad()
super.viewDidLoad()
tav.dataSource = self;
tav.delegate = self;
//backgroundColor
self.view.backgroundColor = UIColor(red: 187, green: 222/255, blue: 251, alpha: 1)
//Url request
let url = "http://localhost:8888/emoji-api/web/app_dev.php/emojis"
let request = NSMutableURLRequest(url: URL(string: url)!)
request.httpMethod = "GET"
let requestAPI = URLSession.shared.dataTask(with: request as URLRequest) data, response, error in
if (error != nil)
print(error!.localizedDescription) // On indique dans la console ou est le problème dans la requête
if let httpStatus = response as? HTTPURLResponse , httpStatus.statusCode != 200
print("statusCode devrait être de 200, mais il est de \(httpStatus.statusCode)")
print("réponse = \(String(describing: response))") // On affiche dans la console si le serveur ne nous renvoit pas un code de 200 qui est le code normal
// let responseAPI = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
//print("responseString = \(String(describing: responseAPI))") // Affiche dans la console la réponse de l'API
if error == nil
// Ce que vous voulez faire.
DispatchQueue.main.async
do
// let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments)
if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]]
for item in parsedData
let emoji = Emoji()
//Transform unicode on an Emoji
let strUnicodeEmoji = String(UnicodeScalar(Int(item["unicode"] as! String, radix: 16)!)!)
print(strUnicodeEmoji)
emoji.emojiString = strUnicodeEmoji as String;
emoji.description = item["description"] as! String;
self.emojisArray.append(emoji)
catch
print("Could not serialise")
requestAPI.resume()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return emojisArray.count;
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = UITableViewCell();
print(emojisArray.count)
let emoji = emojisArray[indexPath.row];
cell.textLabel?.text = emoji.emojiString;
return cell;
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
let defVC = segue.destination as!
SecondViewController;
defVC.emojiSelect = sender as! Emoji
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
let emojiSelect = emojisArray[indexPath.row];
performSegue(withIdentifier: "secondScreen", sender: emojiSelect)
我不修改滚动视图的默认值。 谢谢
【问题讨论】:
在附加self.emojisArray
后,在网络调用的完成块中调用tableView.reloadData()
这是斯威夫特。摆脱所有这些分号。请对使用表视图进行一些搜索。您在cellForRowAt
中创建单元格的代码都是错误的。搜索dequeueReusableCell
这是其他语言的反射
【参考方案1】:
下面的代码会影响性能,您实际上是在添加到 emojisArray 上的每个元素上重新加载 UITableView。
var emojisArray: [Emoji] = []
didSet
tav.reloadData()
用这个替换上面的代码
var emojisArray : [Emoji] = [Emoji]()
当你准备好你的数据源时重新加载你的 UITableView 一次。
do
// let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments)
if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]]
//Creating temporary array for parsing content
var tempArr = [Emoji]()
for item in parsedData
let emoji = Emoji()
//Your parsing code
tempArr.append(emoji)
// Reloading of datasource and UITableView will be done in main thread.
DispatchQueue.main.async
self.emojisArray = tempArr
//Reloading tableView once all parsing is complete
tav.reloadData()
您的 Tableview 必须重用 UITableViewCell 以获得更好的内存利用率,而不是每次都分配一个新的单元格。
替换下面cellForRow
方法的代码
let cell = UITableViewCell();
与
let cell = tableView.dequeueReusableCell(withIdentifier: "Your_Reusable_Cell_Identifier", for: indexPath) as! Your_CustomTableViewCell
注意:要使用可重复使用的自定义 UITableViewCell,您必须将单元格注册到您的 UITableView 见“UITableView - registerClass with Swift”
【讨论】:
感谢您的回答,但我不知道在哪里可以找到/定义“Your_CustomTableViewCell”? 嘿,请通过ralfebert.de/tutorials/ios-swift-uitableviewcontroller/… 创建您自己的自定义 TableViewCell 谢谢你现在它正在工作,我听从了你的建议和这两个教程:ralfebert.de/tutorials/ios-swift-uitableviewcontroller/… 和developer.apple.com/library/content/referencelibrary/…。最终代码swift.sandbox.bluemix.net/#/repl/59c0f56588c199772ebcd59a 很高兴听到这个消息,你实现了你想要的,如果我的回答对你有帮助,请标记为已接受。 我已经浏览了你的最终代码,有建议请减少用一种长方法编写的代码,即 viewDidLoad 。将您的代码分成两个较小的函数,以便更好地阅读和清晰【参考方案2】:检查,您的UITableView
有数据源和委托连接。
出列单元格
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "YOUR_CELL_IDENTIFIER", for: indexPath) as! Your_tableview_cell
let emoji = emojisArray[indexPath.row];
cell.textLabel?.text = emoji.emojiString;
return cell
重新加载表格视图
DispatchQueue.main.async
do
let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments)
if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]]
for item in parsedData
... // your code
...
YOUR_TABLEVIEW.reloadData(); // You have to reload ur tableview
// in main queue after getting
//all values in Array
catch
print("Could not serialise")
【讨论】:
【参考方案3】:您似乎没有对单元格进行出队。有关更多信息,请查看有关重用单元的文档。
let cell = UITableViewCell();
应该是
let cell = tableView.dequeueReusableCell(withIdentifier: "YOUR_CELL_IDENTIFIER", for: indexPath)
如果您使用 Storyboard,则必须在单元格下的 Identity Inspector 中设置单元格标识符。
希望这会有所帮助。
【讨论】:
以上是关于UiTableView cellForRowAt 没有返回好的值并且不能滚动的主要内容,如果未能解决你的问题,请参考以下文章
如何在uitableview的cellForRowAt函数中按标题日期对响应进行排序
UITableView "cellForRowAt: indexPath" 偶尔在 Core Data 属性上调用 "init?(coder aDecoder: NSCo
UiTableView cellForRowAt 没有返回好的值并且不能滚动
在 CellForRowAt 中包含用于自定义 UIView 的 nib 文件,在滚动时会产生 jerk
如何从 cellForRowAt 调用 draw(_ rect: CGRect) 在自定义 tableview 上绘图?