【问题标题】:UiTableView cellForRowAt not return good value and can't scrollUiTableView cellForRowAt 没有返回好的值并且不能滚动
【发布时间】: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
  • 这是其他语言的反射

标签: ios swift uitableview scrollview


【解决方案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

【讨论】:

【解决方案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 中设置单元格标识符。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 2020-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多