Search code examples
iosswiftsearchtableview

Indexpath row is zero after searching


I have been facing issue after searching of tableview. PDF files stored in Firebase are listed in alphabetic order in tableview and can be opened invidually in detailed view as well as after search an item , filtered item can be also viewed without any problem. However, after back to list and click same filtered pdf without refreshing the list, it gives me the first pdf of the list which is that the indexpath.row is zero.

For example, when I search and click on the item with indexpath.row number 3, I reach the relevant pdf file. But when I come back and click on the same filtered item, it brings up the first item of the whole list. Cant figure out how to handle it. Thank you.

import UIKit
import Firebase
import PDFKit

class IcsViewcontroller: UIViewController , UISearchBarDelegate {

var preImage : UIImage?

let cellSpacingHeight: CGFloat = 20

@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var pdfListView: UITableView!

@IBOutlet weak var spinner: UIActivityIndicatorView!

var pdfList = [pdfClass]()

var searchall = [pdfClass]()
var searching = false

override func viewDidLoad() {
    super.viewDidLoad()
    
    pdfListView.delegate = self
    pdfListView.dataSource = self
    searchBar.delegate = self


        self.pdfListView.isHidden = true
   
        
            getPdf()
    
  
}



override func prepare(for segue: UIStoryboardSegue, sender:  Any?) {
   
   if searching {
        let destination = segue.destination as! PdfKitViewController
        let selectedIndexPath = pdfListView.indexPathForSelectedRow
        destination.pdf = searchall[selectedIndexPath!.row]
    } else {
        
        let destination = segue.destination as! PdfKitViewController
        let selectedIndexPath = pdfListView.indexPathForSelectedRow
        destination.pdf = pdfList [selectedIndexPath!.row]
       
        
    }
    
}

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
    
    if searchBar.text == nil || searchBar.text == "" {
               searching = false
           } else {
               searching = true
            
           }
    

}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
    
    searching = false
    
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searching = false
            searchBar.text = ""
            self.pdfListView.reloadData()
   
}

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
   
    searching = false
    
}


func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    

    
   if searchBar.text == nil || searchBar.text == "" {
        searchall = pdfList
        searching = false
        pdfListView.reloadData()
        
    } else {
        
        searching = true
    searchall = pdfList.filter({($0.pdf_name?.lowercased().prefix(searchText.count))! == searchText.lowercased() })
        pdfListView.reloadData()
    }
    
    
}

func getPdf () {
    
    spinner.startAnimating()
    let docRef = Storage.storage().reference().child("ICS_Documents")
    
    docRef.listAll{ (result , error ) in
        
        if let error = error {
         
            print (error )
            
        }
    
        for item in result.items {
            
            
            let storeageLocation = String( describing : item)
            
            let gsReference = Storage.storage().reference(forURL: storeageLocation)
            
            gsReference.downloadURL{ url , error in
                
                //self.pdfList.removeAll()
                
                if let error = error{
                    
                    print(error)
                } else {
                    
                    let pdf_name = String( item.name)
                    let pdf_url = url?.absoluteString
                   
                    let thumbnailSize = CGSize(width: 100, height: 100)
                    
                    let thmbnail = self.generatePdfThumbnail(of: thumbnailSize, for: url!, atPage: 0)
                
                    
                        let pdfall = pdfClass(pdf_name: pdf_name, pdf_url: pdf_url!, pdf_preview: thmbnail!)
                    
                    self.pdfList.append(pdfall)
            
                }
                DispatchQueue.main.async {
                    self.pdfList = self.pdfList.sorted(by: { $0.pdf_name ?? "" < $1.pdf_name ?? ""})
                    self.pdfListView.reloadData()
                    self.spinner.stopAnimating()
                    self.pdfListView.isHidden = false
                    
                }
            }
            
        }
        
        
    }
    
    
    
}
func generatePdfThumbnail(of thumbnailSize: CGSize , for documentUrl: URL, atPage pageIndex: Int) -> UIImage? {
    let pdfDocument = PDFDocument(url: documentUrl)
    let pdfDocumentPage = pdfDocument?.page(at: pageIndex)
    return pdfDocumentPage?.thumbnail(of: thumbnailSize, for: PDFDisplayBox.trimBox)
}


}

extension IcsViewcontroller : UITableViewDelegate,UITableViewDataSource {

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection      section: Int) -> Int {
    
  if searching{
        return searchall.count
    }else {
    return pdfList.count
       
    }
    
}



 
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return cellSpacingHeight
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCell(withIdentifier: "pdfCell", for: indexPath) as! pdfCellTableViewCell
   
   let varcell : pdfClass
    
    if searching {
       varcell = searchall [indexPath.row]
        
    } else {
       varcell = pdfList [indexPath.row]
        
    }
        cell.configure(name: varcell.pdf_name! , pdfthumbnail: varcell.pdf_preview!)
      
    return cell

    
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
   
   var indx : pdfClass
    if searching{
        indx = searchall[indexPath.row ]
        print(indexPath.row )
    }else {
        indx = pdfList[indexPath.row]
    
    }
    performSegue(withIdentifier: "toPdfKit", sender: indx)
    print(indexPath.row)
}



    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    
    let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action:UITableViewRowAction,indexPath:IndexPath)-> Void in
       
        let storage = Storage.storage()
        
        let childsRURL = self.pdfList[indexPath.row].pdf_url
        
        let storageref = storage.reference(forURL: childsRURL!)
        
        storageref.delete{ error in
            if let error = error {
                print(error.localizedDescription)
                
            } else{
                print("File deleted")
                
            }
            
            
        }
        self.pdfListView.reloadData()
        
        
    })
        
    return [deleteAction]
    
    
}

}

This is the pdfClass

import Foundation
import UIKit


class pdfClass : NSObject {

var pdf_name : String?
var pdf_url : String?
var pdf_preview : UIImage?


override init(){
    
    
}

init (pdf_name :String , pdf_url : String, pdf_preview : UIImage ) {
    
    self.pdf_name = pdf_name
    self.pdf_url = pdf_url
    self.pdf_preview = pdf_preview
    
    
}

}

Solution

  • I believe your problem is here, when you click on the cell, your searchBar editing is finished and you make the variable false, changing the list you are working on in the delegate.

       func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
            searching = false
        }
    

    For simplicity, I suggest keeping the original list just to load the results into a helper list that is used throughout the class, rather than working with two lists in each delegate.

    Like this way:

    import UIKit
    
    class Shops {
        private var _familiy_id: String?
        private var _logo : String?
        private var _shopname : String?
    
        var familiy_id : String{
            return _familiy_id!
        }
    
        var shopname : String{
            return _shopname!
        }
        var Logo : String{
            return _logo!
        }
        init(shopname : String , Logo : String , family_id : String) {
            self._shopname = shopname
            self._logo = Logo
            self._familiy_id = family_id
        }
    }
    
    
    
    class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
        @IBOutlet weak var tableView: UITableView!
        @IBOutlet weak var searchBar: UISearchBar!
    
        var shops : [Shops]! = []
        var auxiliar : [Shops]!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // 1 - load data to shops array
            shops.append(Shops(shopname: "Brasil", Logo: "BR", family_id: "1"))
            shops.append(Shops(shopname: "Brasolia", Logo: "BA", family_id: "2"))
            shops.append(Shops(shopname: "Colombia", Logo: "CO", family_id: "3"))
            shops.append(Shops(shopname: "Argentina", Logo: "AR", family_id: "4"))
    
            // 2  - auxiliar receive the complete original array
            auxiliar = shops
    
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return auxiliar.count;
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
            cell.textLabel?.text = auxiliar[indexPath.row].shopname
            return cell
        }
    
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
             auxiliar = shops.filter { $0.shopname.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil }
            if searchText == "" {
                // 3 if there is nothing to search, auxiliar receive the complete orihinal array
                auxiliar = shops
            }
    
            tableView.reloadData()
        }
    }