当我切换选项卡栏控制器屏幕时,表视图为空

发布于 2025-01-14 02:29:05 字数 21292 浏览 1 评论 0原文

我有一个选项卡栏控制器来管理所有视图。我遇到的问题是,当我从 HomeViewController 调用 searchViewController (doAThing()) 中的函数来重新加载 searchViewController 中的 tableView 时,当选项卡栏控制器切换视图时,tableView 为空。

为什么在我的 searchViewController 中调用 doAThing 方法不会刷新我的 tableView? 如何用值填充我的 tableView。

HomeViewController.swift

import UIKit

class HomeViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UISearchBarDelegate{
    
  
    
    
    @IBOutlet weak var productCollectionView: UICollectionView!
    @IBOutlet weak var storesCollectionView: UICollectionView!
    
    @IBOutlet var searchQ: UISearchBar!
    
    @IBOutlet weak var scrollView: UIScrollView!
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if(collectionView == storesCollectionView) {
                return storesImages.count
            }
            return productsImages.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
       
        
        if(collectionView == storesCollectionView) {
            let cell2 = storesCollectionView.dequeueReusableCell(withReuseIdentifier: "storesCell", for: indexPath) as! StoreCollectionViewCell
            cell2.compstoreImage.image = UIImage(named: storesImages[indexPath.row])
            
            return cell2
        }
        else{
            let cell = productCollectionView.dequeueReusableCell(withReuseIdentifier: "productsCell", for: indexPath) as! ProductCollectionViewCell
            cell.pillImage.image = UIImage(named: productsImages[indexPath.row])
            
            return cell
        }
    }
    
    
    
    var productsImages:[String] = ["pcPic", "picturePC"]
    var storesImages:[String] = ["newarkStore", "compeStore"]

    

    override func viewDidLoad() {
        super.viewDidLoad()
        searchQ.delegate = self
        scrollView.contentSize = CGSize(width: self.view.frame.width, height: self.view.frame.height)
        
       // searchQ.delegate = self
        
        

        // Do any additional setup after loading the view.
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        //self.tabBarController?.tabBar.isHidden = false
    }
    
    func searchBarSearchButtonClicked(_ searchQ: UISearchBar)
    {
        print("*********")
        
        let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

        let resultViewController = storyBoard.instantiateViewController(withIdentifier: "SearchViewController") as! searchViewController
       // resultViewController.searchQuery = searchQ
        resultViewController.doAthing(searchQ)
        self.tabBarController?.selectedIndex = 3
      //  NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
        resultViewController.resultsView.reloadData()
      
    }
    
//    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
//
//        print("*********")
//
//        let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "SearchViewController") as! searchViewController
//        secondViewController.doAthing(searchBar)
//        self.navigationController!.pushViewController(secondViewController, animated: true)
//
//
//
//            //let titles: Elements = try doc.select("a[product-thumb]")
//            //let titles: String = try doc.select("a").attr("product-thumb")
//
//           // print(titles
//
//        hideKeyboardWhenTappedAround()
//
//    }
    
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */
   
}

searchViewController.swift

import UIKit
import SwiftSoup

class searchViewController: UIViewController{
   
    

    
    @IBOutlet weak var segmentedControl: UISegmentedControl!
    @IBOutlet weak var resultsView: UITableView!
    @IBOutlet var searchQuery: UISearchBar!
    
//    let content = try! String(contentsOf: URL(string: "https://www.locally.com/search/all/activities/depts?q=bottle")!)
//    let doc: Document = try! SwiftSoup.parse(content)
    
   
    
 
    
    var products: [String] = []
    //let products = ["Computer", "PC", "Laptop"]
    let stores = ["Computer Central", "Fry's Electronics", "Best Buy"]
    //var stores: [String] = []
    let into = ["Custom PC with high performanc. Perfect for gaming and streaming. Great condition", "Custom PC with high performanc. Perfect for gaming and streaming. Great condition", "Custom PC with high performanc. Perfect for gaming and streaming. Great condition"]
    var dollars: [String] = []
    //let dollars = [100, 220, 129, 100, 220, 129]
    let likes = [10, 24, 24, 24 , 456, 46, 46]
    //let miles = ["3.2 mi", "4.1 mi", "6.3 mi", "3.2 mi", "4.1 mi", "6.3 mi"]
    var miles: [String] = []
   // let names = ["Central Computers", "CompE", "geekStore", "Central Computers", "CompE", "geekStore"]
    var names: [String] = []
    let numbers = ["510-329-0172", "510-456-7345", "510-329-0172", "510-329-0172", "510-456-7345", "510-329-0172"]
    var images: [UIImage] = []
    var categories: [String] = []
    var descriptions: [String]  = []
    var stars: [String] = []
    var ratings: [Double] = []
    var ratingImage: [[UIImage]] = [[]]
    var phones: [String] = []
    var cities: [String] = []
    
    //var webCounter:Int = 0
   
        
    
    var x:Double = 0
    var y:Int = 0
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "load"), object: nil)
        
        searchQuery.delegate = self
        resultsView.delegate = self
        resultsView.dataSource = self
        
        //set the height of each row in tableview
        self.resultsView.rowHeight = 200.0
        

        // Do any additional setup after loading the view.
    

        
    }
    
    @objc func loadList(notification: NSNotification) {
        //load data here
        self.resultsView.reloadData()
    }
    
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
            
            //searchBar.inputViewController?.dismissKeyboard()
            searchBar.inputViewController?.dismiss(animated: true)
            
           doAthing(searchBar)
        
        self.searchQuery.endEditing(true)
        self.resultsView.keyboardDismissMode = .onDrag
        hideKeyboardWhenTappedAround()
        
    }
    
        func doAthing(_ searchBar: UISearchBar) {
            
            do {
            
            let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
            
            let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
            loadingIndicator.hidesWhenStopped = true
            loadingIndicator.style = UIActivityIndicatorView.Style.medium
            loadingIndicator.startAnimating();

            alert.view.addSubview(loadingIndicator)
            present(alert, animated: true, completion: nil)
            
                        
            print("reached here")
            let html = try String(contentsOf: URL(string: "https://www.locally.com/search/all/activities/depts?q=" + searchBar.text!)!)
                                  
            //let doc: Document = try SwiftSoup.parse(html)
            guard let titles: Elements = try? SwiftSoup.parse(html).getElementsByClass("product-thumb ") else {return}//select("a") else {return}
            guard let prices: Elements = try? SwiftSoup.parse(html).getElementsByClass("product-thumb-price dl-price") else {return}
            guard let Stores: Elements = try? SwiftSoup.parse(html).getElementsByClass("filter-label-link") else {return}
            guard let Images: Elements = try? SwiftSoup.parse(html).getElementsByClass("product-thumb-img") else {return}
           
            
            
            products = []
            miles = []
            dollars = []
            names = []
            images = []
            stars = []
            
            for title: Element in titles.array() {
                print("title" + String(titles.size()))
                products.append(try! title.attr("data-product-name"))
                
                guard let url: URL = try? URL(string:  "https://www.locally.com/" + String(try! title.attr("href")))
                else
                {
                    miles.append("-")
                    continue
                    
                }
                
                let html1 = try String(contentsOf: url)
                guard let distances: Element = try? SwiftSoup.parse(html1).getElementsByClass("conv-section-distance dl-store-distance").first()
                else
                {
                    miles.append("-")
                    continue
                    
                }
                print(try! distances.ownText())
                miles.append(try! distances.ownText())
                guard let K: Array<String> = try? SwiftSoup.parse(html1).getElementsByClass("breadcrumbs container").eachText() else {return}
                let str = (try! K.last!.components(separatedBy: "/") )
                categories.append(str[str.count - 2])
                print(str[str.count - 2])
                
                guard let desc: Array<String> = try? SwiftSoup.parse(html1).getElementsByClass("pdp-information").eachText() else {return}
                
                guard let s:String = try? desc[1]
                else {
                    return
                }
                descriptions.append( String( s.suffix(s.count - 19) ) )
                print( String( s.suffix(s.count - 19) ) )
                
                guard let star: Element = try? SwiftSoup.parse(html1).getElementsByClass("stars").first()
                else
                {
                    print("no reviews")
                    ratings.append(0)
                    continue
                    
                }
                
                print(try! star.attr("data-rating"))
                //ratings.append(try! star.attr("data-rating")) ?? ()
                
                let x = Double(try! star.attr("data-rating")) ?? 0
                print("y: " + String(Int(x)))
                
                ratings.append(x)
                
                guard let locations: Element = try? SwiftSoup.parse(html1).getElementsByClass("conv-section-store-address section-subtitle dl-store-address js-store-location").first()
                else
                {
                    print("cant find city")
                    return
                }
                
                let string = locations.ownText()
                print("location: " + String(string.prefix(string.count - 10)) )
                cities.append(try! String(string.prefix(string.count - 10)))
                
                
                guard let phoneNums: Element = try? SwiftSoup.parse(html1).getElementsByClass("selected-retailer-info-link btn-action-sm tooltip").first()
                else
                {
                    print("link not found")
                    return
                }
                
                guard let urls:URL = try? URL(string: "https://www.locally.com/" +  phoneNums.attr("href") )
                else
                {
                    return
                }

                let html2 = try String(contentsOf: urls )

                guard let storePage:Element = try? SwiftSoup.parse(html2).getElementsByClass("landing-page-phone-label").first() else {
                    print("Phone Number not found")
                    return
                    
                }
                
                let sp = try? storePage.ownText
                if let s = sp {
                    phones.append(try! s())
                }
                else {
                    phones.append("N/A")
                }

                print(try! storePage.ownText())
//
               // let html1 = try String(contentsOf: url)
                
                
                
                
            }
            for price: Element in prices.array() {
                print("prices" + String(prices.size()))
                print(String(try! price.ownText()))
                dollars.append(try! price.ownText())
            }
            for store: Element in Stores.array() {
                print("Stores" + String(Stores.size()))
                names.append(try! store.ownText()) ?? names.append("N/A")
            }
            for image: Element in Images.array() {
                guard let url = URL(string: try! image.attr("src") ) else { return }
                let data = try? Data(contentsOf: url)
                
                if let imageData = data {
                    images.append( UIImage(data: imageData)! )
                }
                else {
                    images.append(UIImage(named: "pcPic")!)
                }
                //images.append(try! image.downloaded(from: image.attr("src")))
            }
            dismiss(animated: false, completion: nil)
            resultsView.reloadData()
            
            
           
            
            //let titles: Elements = try doc.select("a[product-thumb]")
            //let titles: String = try doc.select("a").attr("product-thumb")
            
           // print(titles)
            
        } catch Exception.Error(type: let type, Message: let message) {
            print(type)
            print(message)
        } catch {
            print("")
        }
        }
    
    
    

    
   
    
    
//    override func viewWillAppear(_ animated: Bool) {
//        super.viewWillAppear(animated)
//        self.tabBarController?.tabBar.isHidden = false
//    }
    
    //When user changes segment, tableview is reloaded
    @IBAction func segmentChanged(_ sender: Any) {
        resultsView.reloadData();
    }
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

    
    func imageWithImage(image: UIImage, scaledToSize newSize: CGSize) -> UIImage {
        
        UIGraphicsBeginImageContext(newSize)
        image.draw(in: CGRect(x: 0 ,y: 20 ,width: newSize.width ,height: newSize.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!.withRenderingMode(.alwaysOriginal)
    }
    
    
    
}


extension searchViewController: UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
    
    
    
        
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("reached here")
        switch segmentedControl.selectedSegmentIndex {
        case 0:
            return products.count
        case 1:
            return stores.count
        case 2:
            return (products.count + stores.count)
        default:
            break
        }
        return 0
    }
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "resultsTableViewCell") as! resultsTableViewCell
        
        switch segmentedControl.selectedSegmentIndex {
        case 0:
            cell.titleLabel?.text = products[indexPath.row]
            cell.productImage?.image = images[indexPath.row]
           // cell.descriptionLabel?.text = into[indexPath.row]
           // cell.descriptionLabel?.numberOfLines = 0
            cell.price?.text = String(dollars[indexPath.row])
            cell.distance?.text = miles[indexPath.row]
            cell.storeName?.numberOfLines = 0
            cell.storeName?.text = names[indexPath.row]
            cell.phoneNumber?.text = phones[indexPath.row]
            let ratNumber = ratings[indexPath.row]
            if( ratNumber == 0 )
            {
                cell.rating?.text = "No Reviews"
            }
            else
            {
                cell.rating?.text = String(ratNumber)
            }
            
            if(ratNumber > 4.5)
            {
                cell.star1.image = UIImage(named: "regular_5")
            }
            else if(ratNumber > 4.0)
            {
                cell.star1.image = UIImage(named: "regular_4_half")
            }
            else if(ratNumber == 4.0)
            {
                cell.star1.image = UIImage(named: "regular_4")
            }
            else if(ratNumber > 3.0)
            {
                cell.star1.image = UIImage(named: "regular_3_half")
            }
            else if(ratNumber == 3.0)
            {
                cell.star1.image = UIImage(named: "regular_3")
            }
            else if(ratNumber > 2.0)
            {
                cell.star1.image = UIImage(named: "regular_2_half")
            }
            else if(ratNumber == 2.0)
            {
                cell.star1.image = UIImage(named: "regular_2")
            }
            else if(ratNumber > 1.0)
            {
                cell.star1.image = UIImage(named: "regular_1_half")
            }
            else if(ratNumber == 1.0)
            {
                cell.star1.image = UIImage(named: "regular_1")
            }
            else
            {
                cell.star1.image = UIImage(named: "regular_0")
            }
            
            cell.rating?.numberOfLines = 0
            
           
           
           // cell.phoneNumber?.text = numbers[indexPath.row]
        case 1:
            cell.titleLabel?.text = stores[indexPath.row]
            cell.productImage?.image = imageWithImage(image: UIImage.init(named: "pcPic")!, scaledToSize: CGSize(width: 400, height: 300))
           // cell.descriptionLabel?.text = into[indexPath.row]
           // cell.descriptionLabel?.numberOfLines = 0
            cell.price?.text = String(dollars[indexPath.row])
            cell.distance?.text = miles[indexPath.row]
            cell.storeName?.text = names[indexPath.row]
            cell.phoneNumber?.text = numbers[indexPath.row]
            
        case 2:
            var all = products + stores
            all.shuffle()
            let alls = into + into
            cell.titleLabel?.text = all[indexPath.row]
            cell.productImage?.image = imageWithImage(image: UIImage.init(named: "pcPic")!, scaledToSize: CGSize(width: 400, height: 300))
         //   cell.descriptionLabel?.text = alls[indexPath.row]
          //  cell.descriptionLabel?.numberOfLines = 0
            cell.price?.text = String(dollars[indexPath.row])
            cell.distance?.text = miles[indexPath.row]
            cell.storeName?.text = names[indexPath.row]
            cell.phoneNumber?.text = numbers[indexPath.row]
        default:
            break
        }
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//        let vc = self.storyboard?.instantiateViewController(withIdentifier: "ShopViewController") as! ShopViewController
//            self.present(vc, animated: true, completion: nil)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let destinationVC = storyboard.instantiateViewController(withIdentifier: "ProductViewController") as! ProductViewController
        destinationVC.ktitle = products[indexPath.row]
        destinationVC.kprice = dollars[indexPath.row]
       // destinationVC.kdescription = [indexPath.row]
        destinationVC.kimage = images[indexPath.row]
//        destinationVC.klikes = likes[indexPath.row]
        destinationVC.kcategory = categories[indexPath.row]
        destinationVC.kdescription = descriptions[indexPath.row]
        destinationVC.kname = names[indexPath.row]
        destinationVC.kmiles = miles[indexPath.row]
        destinationVC.klocation = cities[indexPath.row]
        
        self.present(destinationVC, animated: true, completion: nil)
    }
    
    
}


extension UIViewController {

    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard(_:)))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard(_ sender: UITapGestureRecognizer) {
        view.endEditing(true)

        if let nav = self.navigationController {
            nav.view.endEditing(true)
        }
    }
 }

I have a Tab bar Controller to manage all the views. The problem I'm having is when I call a function in searchViewController (doAThing()) from HomeViewController which reloads the tableView in searchViewController, the tableView is empty when the Tab bar controller switches views.

Why does calling the doAThing method in my searchViewController not refresh my tableView?
How can I fill my tableView with values.

HomeViewController.swift

import UIKit

class HomeViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UISearchBarDelegate{
    
  
    
    
    @IBOutlet weak var productCollectionView: UICollectionView!
    @IBOutlet weak var storesCollectionView: UICollectionView!
    
    @IBOutlet var searchQ: UISearchBar!
    
    @IBOutlet weak var scrollView: UIScrollView!
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if(collectionView == storesCollectionView) {
                return storesImages.count
            }
            return productsImages.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
       
        
        if(collectionView == storesCollectionView) {
            let cell2 = storesCollectionView.dequeueReusableCell(withReuseIdentifier: "storesCell", for: indexPath) as! StoreCollectionViewCell
            cell2.compstoreImage.image = UIImage(named: storesImages[indexPath.row])
            
            return cell2
        }
        else{
            let cell = productCollectionView.dequeueReusableCell(withReuseIdentifier: "productsCell", for: indexPath) as! ProductCollectionViewCell
            cell.pillImage.image = UIImage(named: productsImages[indexPath.row])
            
            return cell
        }
    }
    
    
    
    var productsImages:[String] = ["pcPic", "picturePC"]
    var storesImages:[String] = ["newarkStore", "compeStore"]

    

    override func viewDidLoad() {
        super.viewDidLoad()
        searchQ.delegate = self
        scrollView.contentSize = CGSize(width: self.view.frame.width, height: self.view.frame.height)
        
       // searchQ.delegate = self
        
        

        // Do any additional setup after loading the view.
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        //self.tabBarController?.tabBar.isHidden = false
    }
    
    func searchBarSearchButtonClicked(_ searchQ: UISearchBar)
    {
        print("*********")
        
        let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

        let resultViewController = storyBoard.instantiateViewController(withIdentifier: "SearchViewController") as! searchViewController
       // resultViewController.searchQuery = searchQ
        resultViewController.doAthing(searchQ)
        self.tabBarController?.selectedIndex = 3
      //  NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
        resultViewController.resultsView.reloadData()
      
    }
    
//    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
//
//        print("*********")
//
//        let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "SearchViewController") as! searchViewController
//        secondViewController.doAthing(searchBar)
//        self.navigationController!.pushViewController(secondViewController, animated: true)
//
//
//
//            //let titles: Elements = try doc.select("a[product-thumb]")
//            //let titles: String = try doc.select("a").attr("product-thumb")
//
//           // print(titles
//
//        hideKeyboardWhenTappedAround()
//
//    }
    
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */
   
}

searchViewController.swift

import UIKit
import SwiftSoup

class searchViewController: UIViewController{
   
    

    
    @IBOutlet weak var segmentedControl: UISegmentedControl!
    @IBOutlet weak var resultsView: UITableView!
    @IBOutlet var searchQuery: UISearchBar!
    
//    let content = try! String(contentsOf: URL(string: "https://www.locally.com/search/all/activities/depts?q=bottle")!)
//    let doc: Document = try! SwiftSoup.parse(content)
    
   
    
 
    
    var products: [String] = []
    //let products = ["Computer", "PC", "Laptop"]
    let stores = ["Computer Central", "Fry's Electronics", "Best Buy"]
    //var stores: [String] = []
    let into = ["Custom PC with high performanc. Perfect for gaming and streaming. Great condition", "Custom PC with high performanc. Perfect for gaming and streaming. Great condition", "Custom PC with high performanc. Perfect for gaming and streaming. Great condition"]
    var dollars: [String] = []
    //let dollars = [100, 220, 129, 100, 220, 129]
    let likes = [10, 24, 24, 24 , 456, 46, 46]
    //let miles = ["3.2 mi", "4.1 mi", "6.3 mi", "3.2 mi", "4.1 mi", "6.3 mi"]
    var miles: [String] = []
   // let names = ["Central Computers", "CompE", "geekStore", "Central Computers", "CompE", "geekStore"]
    var names: [String] = []
    let numbers = ["510-329-0172", "510-456-7345", "510-329-0172", "510-329-0172", "510-456-7345", "510-329-0172"]
    var images: [UIImage] = []
    var categories: [String] = []
    var descriptions: [String]  = []
    var stars: [String] = []
    var ratings: [Double] = []
    var ratingImage: [[UIImage]] = [[]]
    var phones: [String] = []
    var cities: [String] = []
    
    //var webCounter:Int = 0
   
        
    
    var x:Double = 0
    var y:Int = 0
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "load"), object: nil)
        
        searchQuery.delegate = self
        resultsView.delegate = self
        resultsView.dataSource = self
        
        //set the height of each row in tableview
        self.resultsView.rowHeight = 200.0
        

        // Do any additional setup after loading the view.
    

        
    }
    
    @objc func loadList(notification: NSNotification) {
        //load data here
        self.resultsView.reloadData()
    }
    
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
            
            //searchBar.inputViewController?.dismissKeyboard()
            searchBar.inputViewController?.dismiss(animated: true)
            
           doAthing(searchBar)
        
        self.searchQuery.endEditing(true)
        self.resultsView.keyboardDismissMode = .onDrag
        hideKeyboardWhenTappedAround()
        
    }
    
        func doAthing(_ searchBar: UISearchBar) {
            
            do {
            
            let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
            
            let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
            loadingIndicator.hidesWhenStopped = true
            loadingIndicator.style = UIActivityIndicatorView.Style.medium
            loadingIndicator.startAnimating();

            alert.view.addSubview(loadingIndicator)
            present(alert, animated: true, completion: nil)
            
                        
            print("reached here")
            let html = try String(contentsOf: URL(string: "https://www.locally.com/search/all/activities/depts?q=" + searchBar.text!)!)
                                  
            //let doc: Document = try SwiftSoup.parse(html)
            guard let titles: Elements = try? SwiftSoup.parse(html).getElementsByClass("product-thumb ") else {return}//select("a") else {return}
            guard let prices: Elements = try? SwiftSoup.parse(html).getElementsByClass("product-thumb-price dl-price") else {return}
            guard let Stores: Elements = try? SwiftSoup.parse(html).getElementsByClass("filter-label-link") else {return}
            guard let Images: Elements = try? SwiftSoup.parse(html).getElementsByClass("product-thumb-img") else {return}
           
            
            
            products = []
            miles = []
            dollars = []
            names = []
            images = []
            stars = []
            
            for title: Element in titles.array() {
                print("title" + String(titles.size()))
                products.append(try! title.attr("data-product-name"))
                
                guard let url: URL = try? URL(string:  "https://www.locally.com/" + String(try! title.attr("href")))
                else
                {
                    miles.append("-")
                    continue
                    
                }
                
                let html1 = try String(contentsOf: url)
                guard let distances: Element = try? SwiftSoup.parse(html1).getElementsByClass("conv-section-distance dl-store-distance").first()
                else
                {
                    miles.append("-")
                    continue
                    
                }
                print(try! distances.ownText())
                miles.append(try! distances.ownText())
                guard let K: Array<String> = try? SwiftSoup.parse(html1).getElementsByClass("breadcrumbs container").eachText() else {return}
                let str = (try! K.last!.components(separatedBy: "/") )
                categories.append(str[str.count - 2])
                print(str[str.count - 2])
                
                guard let desc: Array<String> = try? SwiftSoup.parse(html1).getElementsByClass("pdp-information").eachText() else {return}
                
                guard let s:String = try? desc[1]
                else {
                    return
                }
                descriptions.append( String( s.suffix(s.count - 19) ) )
                print( String( s.suffix(s.count - 19) ) )
                
                guard let star: Element = try? SwiftSoup.parse(html1).getElementsByClass("stars").first()
                else
                {
                    print("no reviews")
                    ratings.append(0)
                    continue
                    
                }
                
                print(try! star.attr("data-rating"))
                //ratings.append(try! star.attr("data-rating")) ?? ()
                
                let x = Double(try! star.attr("data-rating")) ?? 0
                print("y: " + String(Int(x)))
                
                ratings.append(x)
                
                guard let locations: Element = try? SwiftSoup.parse(html1).getElementsByClass("conv-section-store-address section-subtitle dl-store-address js-store-location").first()
                else
                {
                    print("cant find city")
                    return
                }
                
                let string = locations.ownText()
                print("location: " + String(string.prefix(string.count - 10)) )
                cities.append(try! String(string.prefix(string.count - 10)))
                
                
                guard let phoneNums: Element = try? SwiftSoup.parse(html1).getElementsByClass("selected-retailer-info-link btn-action-sm tooltip").first()
                else
                {
                    print("link not found")
                    return
                }
                
                guard let urls:URL = try? URL(string: "https://www.locally.com/" +  phoneNums.attr("href") )
                else
                {
                    return
                }

                let html2 = try String(contentsOf: urls )

                guard let storePage:Element = try? SwiftSoup.parse(html2).getElementsByClass("landing-page-phone-label").first() else {
                    print("Phone Number not found")
                    return
                    
                }
                
                let sp = try? storePage.ownText
                if let s = sp {
                    phones.append(try! s())
                }
                else {
                    phones.append("N/A")
                }

                print(try! storePage.ownText())
//
               // let html1 = try String(contentsOf: url)
                
                
                
                
            }
            for price: Element in prices.array() {
                print("prices" + String(prices.size()))
                print(String(try! price.ownText()))
                dollars.append(try! price.ownText())
            }
            for store: Element in Stores.array() {
                print("Stores" + String(Stores.size()))
                names.append(try! store.ownText()) ?? names.append("N/A")
            }
            for image: Element in Images.array() {
                guard let url = URL(string: try! image.attr("src") ) else { return }
                let data = try? Data(contentsOf: url)
                
                if let imageData = data {
                    images.append( UIImage(data: imageData)! )
                }
                else {
                    images.append(UIImage(named: "pcPic")!)
                }
                //images.append(try! image.downloaded(from: image.attr("src")))
            }
            dismiss(animated: false, completion: nil)
            resultsView.reloadData()
            
            
           
            
            //let titles: Elements = try doc.select("a[product-thumb]")
            //let titles: String = try doc.select("a").attr("product-thumb")
            
           // print(titles)
            
        } catch Exception.Error(type: let type, Message: let message) {
            print(type)
            print(message)
        } catch {
            print("")
        }
        }
    
    
    

    
   
    
    
//    override func viewWillAppear(_ animated: Bool) {
//        super.viewWillAppear(animated)
//        self.tabBarController?.tabBar.isHidden = false
//    }
    
    //When user changes segment, tableview is reloaded
    @IBAction func segmentChanged(_ sender: Any) {
        resultsView.reloadData();
    }
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

    
    func imageWithImage(image: UIImage, scaledToSize newSize: CGSize) -> UIImage {
        
        UIGraphicsBeginImageContext(newSize)
        image.draw(in: CGRect(x: 0 ,y: 20 ,width: newSize.width ,height: newSize.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!.withRenderingMode(.alwaysOriginal)
    }
    
    
    
}


extension searchViewController: UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
    
    
    
        
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("reached here")
        switch segmentedControl.selectedSegmentIndex {
        case 0:
            return products.count
        case 1:
            return stores.count
        case 2:
            return (products.count + stores.count)
        default:
            break
        }
        return 0
    }
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "resultsTableViewCell") as! resultsTableViewCell
        
        switch segmentedControl.selectedSegmentIndex {
        case 0:
            cell.titleLabel?.text = products[indexPath.row]
            cell.productImage?.image = images[indexPath.row]
           // cell.descriptionLabel?.text = into[indexPath.row]
           // cell.descriptionLabel?.numberOfLines = 0
            cell.price?.text = String(dollars[indexPath.row])
            cell.distance?.text = miles[indexPath.row]
            cell.storeName?.numberOfLines = 0
            cell.storeName?.text = names[indexPath.row]
            cell.phoneNumber?.text = phones[indexPath.row]
            let ratNumber = ratings[indexPath.row]
            if( ratNumber == 0 )
            {
                cell.rating?.text = "No Reviews"
            }
            else
            {
                cell.rating?.text = String(ratNumber)
            }
            
            if(ratNumber > 4.5)
            {
                cell.star1.image = UIImage(named: "regular_5")
            }
            else if(ratNumber > 4.0)
            {
                cell.star1.image = UIImage(named: "regular_4_half")
            }
            else if(ratNumber == 4.0)
            {
                cell.star1.image = UIImage(named: "regular_4")
            }
            else if(ratNumber > 3.0)
            {
                cell.star1.image = UIImage(named: "regular_3_half")
            }
            else if(ratNumber == 3.0)
            {
                cell.star1.image = UIImage(named: "regular_3")
            }
            else if(ratNumber > 2.0)
            {
                cell.star1.image = UIImage(named: "regular_2_half")
            }
            else if(ratNumber == 2.0)
            {
                cell.star1.image = UIImage(named: "regular_2")
            }
            else if(ratNumber > 1.0)
            {
                cell.star1.image = UIImage(named: "regular_1_half")
            }
            else if(ratNumber == 1.0)
            {
                cell.star1.image = UIImage(named: "regular_1")
            }
            else
            {
                cell.star1.image = UIImage(named: "regular_0")
            }
            
            cell.rating?.numberOfLines = 0
            
           
           
           // cell.phoneNumber?.text = numbers[indexPath.row]
        case 1:
            cell.titleLabel?.text = stores[indexPath.row]
            cell.productImage?.image = imageWithImage(image: UIImage.init(named: "pcPic")!, scaledToSize: CGSize(width: 400, height: 300))
           // cell.descriptionLabel?.text = into[indexPath.row]
           // cell.descriptionLabel?.numberOfLines = 0
            cell.price?.text = String(dollars[indexPath.row])
            cell.distance?.text = miles[indexPath.row]
            cell.storeName?.text = names[indexPath.row]
            cell.phoneNumber?.text = numbers[indexPath.row]
            
        case 2:
            var all = products + stores
            all.shuffle()
            let alls = into + into
            cell.titleLabel?.text = all[indexPath.row]
            cell.productImage?.image = imageWithImage(image: UIImage.init(named: "pcPic")!, scaledToSize: CGSize(width: 400, height: 300))
         //   cell.descriptionLabel?.text = alls[indexPath.row]
          //  cell.descriptionLabel?.numberOfLines = 0
            cell.price?.text = String(dollars[indexPath.row])
            cell.distance?.text = miles[indexPath.row]
            cell.storeName?.text = names[indexPath.row]
            cell.phoneNumber?.text = numbers[indexPath.row]
        default:
            break
        }
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//        let vc = self.storyboard?.instantiateViewController(withIdentifier: "ShopViewController") as! ShopViewController
//            self.present(vc, animated: true, completion: nil)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let destinationVC = storyboard.instantiateViewController(withIdentifier: "ProductViewController") as! ProductViewController
        destinationVC.ktitle = products[indexPath.row]
        destinationVC.kprice = dollars[indexPath.row]
       // destinationVC.kdescription = [indexPath.row]
        destinationVC.kimage = images[indexPath.row]
//        destinationVC.klikes = likes[indexPath.row]
        destinationVC.kcategory = categories[indexPath.row]
        destinationVC.kdescription = descriptions[indexPath.row]
        destinationVC.kname = names[indexPath.row]
        destinationVC.kmiles = miles[indexPath.row]
        destinationVC.klocation = cities[indexPath.row]
        
        self.present(destinationVC, animated: true, completion: nil)
    }
    
    
}


extension UIViewController {

    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard(_:)))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard(_ sender: UITapGestureRecognizer) {
        view.endEditing(true)

        if let nav = self.navigationController {
            nav.view.endEditing(true)
        }
    }
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰之心 2025-01-21 02:29:05

首先,以这种方式切换到不同的选项卡可能不是一个好主意。用户知道点击选项卡栏图标/按钮会将他们带到新选项卡。如果您通过代码在选项卡中跳转,则可能会让用户感到非常困惑。

但是...这是你的应用程序。

您的代码不“刷新我的 tableView”的原因是因为您从未真正引用该视图控制器。

在您的代码中:

func searchBarSearchButtonClicked(_ searchQ: UISearchBar)
{
    print("*********")

    let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

    // here you create a NEW instance of searchViewController
    let resultViewController = storyBoard.instantiateViewController(withIdentifier: "SearchViewController") as! searchViewController

    // you call a func in that instance
    resultViewController.doAthing(searchQ)

    // you switch to tab index 3, which holds an OLD instance of searchViewController
    self.tabBarController?.selectedIndex = 3

    // you tell resultsView in the NEW instance to reloadData()
    resultViewController.resultsView.reloadData()

    // as soon as you exit this func, the NEW instance is deleted
}

可以执行以下操作:

func searchBarSearchButtonClicked(_ searchQ: UISearchBar)
    
    print("*********")

    // get a reference to the searchViewController that is already
    //  part of the tab bar controller
    if let tb = self.tabBarController,
       let controllers = tb.viewControllers,
       let resultVC = controllers[3] as? searchViewController {
        
        // call the func
        resultVC.doAthing("new")

        tb.selectedIndex = 3
    }
    
}

但是,这确实不是一个好方法...仅举一个例子,假设您在某个时刻更改选项卡的顺序?

您最好使用自定义选项卡栏控制器类,或使用“数据管理器”类。

我建议您前往谷歌(或您最喜欢的搜索引擎)并搜索标签栏视图控制器之间的快速传递数据 - 您会发现大量讨论、文章、示例等。


编辑 -- 注释

HomeViewController 中,将 func searchBarSearchButtonClicked 替换为:

func searchBarSearchButtonClicked(_ searchQ: UISearchBar)
{
    
    print("1 - searchBarSearchButtonClicked")
    
    guard let btnTitle = searchQ.largeContentTitle else {
        print("2 - FAILED to get searchQ.largeContentTitle")
        return
    }
    
    print("2 - got btnTitle", btnTitle)
    
    if let tb = self.tabBarController {
        print("3 - got a tab bar controller reference")
        if let controllers = tb.viewControllers {
            print("4 - got controllers reference")
            if controllers.count == 4 {
                print("5 - we have 4 controllers")
                if let resultVC = controllers[3] as? searchViewController {
                    
                    print("6 - got a reference to searchViewController")

                    // if we have not yet selected the 4th tab,
                    //    the view will not yet have been loaded
                    //    so make sure it is
                    resultVC.loadViewIfNeeded()
                    
                    // call the func, passing the button title
                    resultVC.doAthing(searchQ)
                    
                    // switch to the 4th tab
                    tb.selectedIndex = 3

                    print("7 - we should now be at searchViewController")
                    
                } else {
                    print("6 - FAILED TO GET a reference to searchViewController")
                }
            } else {
                print("5 - FAILED TO GET a reference to searchViewController")
            }
        } else {
            print("4 - FAILED TO GET a reference to searchViewController")
        }
    } else {
        print("3 - FAILED TO GET a reference to searchViewController")
    }
    
}

然后查看将哪些消息打印到调试控制台。

First, it's probably not a good idea to switch to a different tab in that manner. Users understand that tapping a tab-bar icon/button takes them to a new tab. If you're jumping around in the tabs via code, it can be very confusing for the user.

But... it's your app.

The reason your code does not "refresh my tableView" is because you never actually reference that view controller.

In your code:

func searchBarSearchButtonClicked(_ searchQ: UISearchBar)
{
    print("*********")

    let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

    // here you create a NEW instance of searchViewController
    let resultViewController = storyBoard.instantiateViewController(withIdentifier: "SearchViewController") as! searchViewController

    // you call a func in that instance
    resultViewController.doAthing(searchQ)

    // you switch to tab index 3, which holds an OLD instance of searchViewController
    self.tabBarController?.selectedIndex = 3

    // you tell resultsView in the NEW instance to reloadData()
    resultViewController.resultsView.reloadData()

    // as soon as you exit this func, the NEW instance is deleted
}

You could do something like this:

func searchBarSearchButtonClicked(_ searchQ: UISearchBar)
    
    print("*********")

    // get a reference to the searchViewController that is already
    //  part of the tab bar controller
    if let tb = self.tabBarController,
       let controllers = tb.viewControllers,
       let resultVC = controllers[3] as? searchViewController {
        
        // call the func
        resultVC.doAthing("new")

        tb.selectedIndex = 3
    }
    
}

However, that's really not a great approach... Just for one example, Suppose you change the order of the tabs at some point?

You're better off using either a custom tab bar controller class, or using a "data manager" class.

I'd suggest you head over to google (or your favorite search engine) and search for swift pass data between tab bar view controllers -- you'll find plenty of discussions, articles, examples, etc.


Edit -- comment

In HomeViewController replace your func searchBarSearchButtonClicked with this:

func searchBarSearchButtonClicked(_ searchQ: UISearchBar)
{
    
    print("1 - searchBarSearchButtonClicked")
    
    guard let btnTitle = searchQ.largeContentTitle else {
        print("2 - FAILED to get searchQ.largeContentTitle")
        return
    }
    
    print("2 - got btnTitle", btnTitle)
    
    if let tb = self.tabBarController {
        print("3 - got a tab bar controller reference")
        if let controllers = tb.viewControllers {
            print("4 - got controllers reference")
            if controllers.count == 4 {
                print("5 - we have 4 controllers")
                if let resultVC = controllers[3] as? searchViewController {
                    
                    print("6 - got a reference to searchViewController")

                    // if we have not yet selected the 4th tab,
                    //    the view will not yet have been loaded
                    //    so make sure it is
                    resultVC.loadViewIfNeeded()
                    
                    // call the func, passing the button title
                    resultVC.doAthing(searchQ)
                    
                    // switch to the 4th tab
                    tb.selectedIndex = 3

                    print("7 - we should now be at searchViewController")
                    
                } else {
                    print("6 - FAILED TO GET a reference to searchViewController")
                }
            } else {
                print("5 - FAILED TO GET a reference to searchViewController")
            }
        } else {
            print("4 - FAILED TO GET a reference to searchViewController")
        }
    } else {
        print("3 - FAILED TO GET a reference to searchViewController")
    }
    
}

Then see what messages get printed to the debug console.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文