快速单击表格视图单元格时显示索引超出范围或返回主屏幕

Posted

技术标签:

【中文标题】快速单击表格视图单元格时显示索引超出范围或返回主屏幕【英文标题】:Swift when clicking on table view cell it says index out of range or goes back to the home screen 【发布时间】:2018-03-07 03:26:17 【问题描述】:

由于某种原因,当我单击表格视图单元格时,它会将我踢出应用程序或说索引超出范围。正在传递信息,因为它在表格视图单元格中显示书名,不确定为什么它不起作用。任何帮助将不胜感激

连接booksearchview和inroviewcontroller的segue是正确的

用于搜索书籍的视图控制器

import UIKit
import Foundation

class ViewController: UIViewController, UITextFieldDelegate 

@IBOutlet weak var bookTitleTextField: UITextField!
@IBOutlet weak var authorTextField: UITextField!

var book: String = ""
var author: String = ""

var bookCoversInfo = [UIImage]()
var titlesInfo = [String]()
var authorsInfo = [String]()
var yearInfo = [String]()
var pagesInfo = [String]()
var starRatingInfo = [UIImage]()
var starRatingCountInfo = [Double]()
var reviewsInfo = [String]()
var descriptionsInfo = [String]()

override func viewDidLoad() 
    super.viewDidLoad()
    bookTitleTextField.delegate = self
    authorTextField.delegate = self


func textFieldShouldReturn(_ textField: UITextField) -> Bool 
    bookTitleTextField.resignFirstResponder()
    authorTextField.resignFirstResponder()
    return true;


func initializeTextFields() 
    bookTitleTextField.delegate = self
    bookTitleTextField.keyboardType = UIKeyboardType.default

    authorTextField.delegate = self
    authorTextField.keyboardType = UIKeyboardType.default


@IBAction func searchButton(_ sender: UIButton) 

    var query = ""

    if let book = bookTitleTextField.text, let author = authorTextField.text 
        query = book
        if (!query.isEmpty) 
            query += "+"
        
        query += "inauthor\(author)"
    

    if let book = bookTitleTextField.text 
        query = book
    

    if let author = authorTextField.text 
        if (!query.isEmpty) 
            query += "+"
        
        query += "inauthor:\(author)"
    

    let session: URLSession = 
        let config = URLSessionConfiguration.default
        return URLSession(configuration: config)
    ()

    let queryItems = [NSURLQueryItem(name: "q", value: query)]
    let urlComps = NSURLComponents(string: "https://www.googleapis.com/books/v1/volumes?")!
    urlComps.queryItems = queryItems as [URLQueryItem]
    let booksURL = urlComps.url!

    let request = URLRequest(url: booksURL)

 //   let request = URLRequest(url: urlComps.url!)

    let task = session.dataTask(with: request) 
        (data, response, error) -> Void in
        if let jsonData = data 
            if let jsonString = try? JSONSerialization.jsonObject(with: jsonData, options: []) 
                    let arrayOfTitles = (jsonString as AnyObject).value(forKeyPath: "items.volumeInfo.title") as? [String]
                    if let items = arrayOfTitles 
                        self.titlesInfo = items
                    

                    let arrayOfAuthors = (jsonString as AnyObject).value(forKeyPath: "items.volumeInfo.authors") as? [String]
                    if let itemsA = arrayOfAuthors 
                        self.authorsInfo = itemsA
                    

              //  let arrayOfYear = (jsonString as AnyObject).value(forKeyPath: "items.volumeInfo.pageCount") as? [String]
                   let arrayOfPage = (jsonString as AnyObject).value(forKeyPath: "items.volumeInfo.pageCount") as? [String]
                    if let itemPages = arrayOfPage 
                        self.pagesInfo = itemPages
                    

                    let arrayOfRatings = (jsonString as AnyObject).value(forKeyPath:    "items.volumeInfo.averageRating") as? [UIImage]
                    if let itemStars = arrayOfRatings 
                        self.starRatingInfo = itemStars
                    

                    let arrayOfReviews = (jsonString as AnyObject).value(forKeyPath: "items.volumeInfo.ratingsCount") as? [String]
                    if let itemRating = arrayOfReviews 
                        self.reviewsInfo = itemRating
                    

                    let arrayOfStarsCount = (jsonString as AnyObject).value(forKeyPath:    "items.volumeInfo.averageRating") as? [Double]
                    if let itemStarsCount = arrayOfStarsCount 
                        self.starRatingCountInfo = itemStarsCount
                    

                    let arrayOfDescription = (jsonString as AnyObject).value(forKeyPath: "items.volumeInfo.description") as? [String]
                    if let itemDescription = arrayOfDescription 
                        self.descriptionsInfo = itemDescription
                    

                    let arrayOfBookCover = (jsonString as AnyObject).value(forKeyPath: "items.volumeInfo.imageLinks.thumbnail") as? [UIImage]
                    if let itemCover = arrayOfBookCover 
                        self.bookCoversInfo = itemCover
                    

                    DispatchQueue.main.async 
                        self.performSegue(withIdentifier: "findTitles", sender: self)
                    
            
        
            else 
                print("Error fetching books \(error.debugDescription)")
            
        
    task.resume()


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    bookTitleTextField.resignFirstResponder()
    authorTextField.resignFirstResponder()


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if (segue.identifier == "findTitles") 
        if let destinationVC = segue.destination as? BookSearchView 
            destinationVC.bookCoversReady = bookCoversInfo
            destinationVC.booksReady = titlesInfo
            destinationVC.authorsReady = authorsInfo
            destinationVC.yearReady = yearInfo
            destinationVC.pagesReady = pagesInfo
            destinationVC.starRatingReady = starRatingInfo
            destinationVC.starRatingCountReady = starRatingCountInfo
            destinationVC.reviewsReady = reviewsInfo
            destinationVC.descriptionsReady = descriptionsInfo
        
    



我的图书搜索表格视图单元格在哪里

import UIKit
 import Foundation

 var myIndex = 0

class BookSearchView: UITableViewController 

var bookCoversReady = [UIImage]()
var booksReady = [String]()
var authorsReady = [String]()
var yearReady = [String]()
var pagesReady = [String]()
var starRatingReady = [UIImage]()
var starRatingCountReady = [Double]()
var reviewsReady = [String]()
var descriptionsReady = [String]()

var bookCoversSend: UIImage?
var titleSend: String = ""
var authorsSend: String = ""
var yearSend: String = ""
var pagesSend: String = ""
var starRatingSend: UIImage?
var starRatingCountSend: Double = 0.0
var reviewsSend: String = ""
var descriptionsSend: String = ""

override func viewDidLoad() 
   super.viewDidLoad()


override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)
    tableView.reloadData()


override func numberOfSections(in tableView: UITableView) -> Int 
    return 2


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return booksReady.count


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    cell.textLabel?.text = booksReady[indexPath.row]
    cell.detailTextLabel?.text = authorsReady[indexPath.row]
    return cell


override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        myIndex = indexPath.row
    // bookCoversSend = bookCoversReady[indexPath.row]
         //  titleSend = booksReady[indexPath.row]
       //    authorsSend = authorsReady[indexPath.row]
       //    yearSend = yearReady[indexPath.row]
        //   pagesSend = pagesReady[indexPath.row]
        //   starRatingSend = starRatingReady[indexPath.row]
        //   starRatingCountSend = starRatingCountReady[indexPath.row]
        //   reviewsSend = reviewsReady[indexPath.row]
        //   descriptionsSend = descriptionsReady[indexPath.row]
    DispatchQueue.main.async 
        self.performSegue(withIdentifier: "bookInfo", sender: self)
    


func prepareForSegue(segue: UIStoryboardSegue, sender: Any?) 
    if (segue.identifier == "bookInfo") 
        if let destinationVC = segue.destination as? InfoViewController 
            destinationVC.bookCoversDisplay = bookCoversReady
            destinationVC.titlesDisplay = booksReady
            destinationVC.authorsDisplay = authorsReady
            destinationVC.yearDisplay = yearReady
            destinationVC.pagesDisplay = pagesReady
            destinationVC.starRatingDisplay = starRatingReady
            destinationVC.starRatingNumber = starRatingCountReady
            destinationVC.reviewsDisplay = reviewsReady
            destinationVC.descriptionsDisplay = descriptionsReady
        
    


用于显示图书信息的信息视图控制器

 import UIKit
import Foundation

class InfoViewController: UIViewController 

@IBOutlet var bookTitleLabel: UILabel!
@IBOutlet var authorLabel: UILabel!
@IBOutlet var bookYear: UILabel!
@IBOutlet var numberOfPages: UILabel!
@IBOutlet var totalReviews: UILabel!
@IBOutlet var descriptionLabel: UILabel!
@IBOutlet var bookCoverImage: UIImageView!
@IBOutlet var ratingStars: UIImageView!

  var titlesDisplay = [String]()
var authorsDisplay = [String]()
  var yearDisplay = [String]()
  var pagesDisplay = [String]()
  var starRatingNumber = [Double]()
  var reviewsDisplay = [String]()
  var descriptionsDisplay = [String]()
  var bookCoversDisplay = [UIImage]()
  var starRatingDisplay = [UIImage]()

override func viewDidLoad() 
    super.viewDidLoad()

    bookCoverImage.image = bookCoversDisplay[myIndex]
    bookTitleLabel.text = titlesDisplay[myIndex]
    authorLabel.text = authorsDisplay[myIndex]
    bookYear.text = yearDisplay[myIndex]
    numberOfPages.text = pagesDisplay[myIndex]
    ratingStars.image = starRatingDisplay[myIndex]
    let starRating = starRatingNumber[myIndex]
    totalReviews.text = reviewsDisplay[myIndex]
    descriptionLabel.text = descriptionsDisplay[myIndex]

    if starRating < 0.5 
        ratingStars.image = UIImage(named: "zerostars")
     else if starRating >= 0.5 && starRating < 1.0 
        ratingStars.image = UIImage(named: "halfstar")
     else if starRating >= 1.0 && starRating < 1.5 
        ratingStars.image = UIImage(named: "onestar")
     else if starRating >= 1.5 && starRating < 2.0 
        ratingStars.image = UIImage(named: "onehalfstar")
     else if starRating >= 2.0 && starRating < 2.5 
        ratingStars.image = UIImage(named: "twostars")
     else if starRating >= 2.5 && starRating < 3.0 
        ratingStars.image = UIImage(named: "twohalfstars")
     else if starRating >= 3.0 && starRating < 3.5 
        ratingStars.image = UIImage(named: "threestars")
     else if starRating >= 3.5 && starRating < 4.0 
        ratingStars.image = UIImage(named: "threehalfstars")
     else if starRating >= 4.0 && starRating < 4.5 
        ratingStars.image = UIImage(named: "fourstars")
     else if starRating >= 4.5 && starRating < 5.0 
        ratingStars.image = UIImage(named: "fourhalfstars")
     else if starRating == 5.0 
        ratingStars.image = UIImage(named: "fivestars")
    

   //  bookCoverImage.image = bookCoversDisplay
  //   bookTitleLabel.text = titlesDisplay
  //   authorLabel.text = authorsDisplay
  //   bookYear.text = yearDisplay
  //   numberOfPages.text = pagesDisplay
  //   ratingStars.image = starRatingDisplay
  //   totalReviews.text = reviewsDisplay
  //   descriptionLabel.text = descriptionsDisplay



【问题讨论】:

问题可能出在 InfoViewController viewDidLoad 中,请确保 myIndex 小于数组计数。 我检查了每个数组计数,但是当我测试时,它只是在进行编辑之前显示正常屏幕。 【参考方案1】:

在您的 BookSearchView 中,我认为您将返回 2 个部分以在 tableview 中显示两个部分,其中一个将显示书籍内容,另一个将显示作者内容。 如果是这样的话,

你需要像这样有条件地返回 numberOfRowsInSection

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    switch section 
      case 0: return booksReady.count
      case 1: return authorsReady.count
      default: return 0
  

由于您尝试访问尚未在 numberOfRowsInSection 中定义的 authorsready 索引,因此您遇到索引超出范围错误。

【讨论】:

这使得我的标题不会在表格视图单元格中重复。当我单击一个表格视图单元格时,它仍然会返回主屏幕。 除了title和description之外的其他数组还是0【参考方案2】:

如果您将作者姓名代码更改如下,它将起作用。因为作者姓名是以 Array of Array 的形式出现的。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = booksReady[indexPath.row] as? String
        var authorNames = authorsReady[0] as! [Any]
        let authorNamesStr = authorNames[indexPath.row] as! [Any]
        cell.detailTextLabel?.text = authorNamesStr[0] as? String
        return cell
    

【讨论】:

以上是关于快速单击表格视图单元格时显示索引超出范围或返回主屏幕的主要内容,如果未能解决你的问题,请参考以下文章

在我的表格视图中设置单元格时索引超出范围

自定义表格视图单元格中的 UITextField。点击单元格/文本字段时显示选择器视图

点击表格视图单元格时显示操作表

选择表格视图单元格时显示自定义 UIImageView

单击表格视图单元格时加载缓慢

Swift 表格视图返回我的字典的一些单元格