0

enter image description hereenter image description hereenter image description hereenter image description hereI am trying to create a dictionary type app with section header, title text, and subtitle text. I managed to get everything to work using the following code. The only thing I can't figure out is how to filter the UISearchBar to show the results of the String [Coptic] within the array. Is this even possible the way I organized everything or do I need to restructure? Does anyone have any suggestions?

I left the code for the updateSearchResults blank on the bottom because I don't know what to code.

 class Gamma: UITableViewController, UISearchBarDelegate, UISearchResultsUpdating {


    struct words {

        var sectionName : String!
        var coptic : [String]!
        var english : [String]!
    }

    var array = [words]()
    var filtered = [words]()
    var filtered2 = UITableViewController()

    var indexarray = ["Ga", "Ge", "Gy", "Gn", "Go", "Gr", "Gw"]

    let searchController = UISearchController(searchResultsController: nil)




    override func viewDidLoad() {
        super.viewDidLoad()


        let defaultTextAttribs = [NSAttributedStringKey.font.rawValue: UIFont(name:"CS Avva Shenouda", size:17), NSAttributedStringKey.foregroundColor.rawValue:UIColor.black]


        UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = defaultTextAttribs as Any as! [String : Any]


        self.navigationController?.navigationBar.tintColor = UIColor.white

        filtered = array

        searchController.searchResultsUpdater = self
        searchController.hidesNavigationBarDuringPresentation = false
        searchController.dimsBackgroundDuringPresentation = false


        self.navigationItem.titleView = searchController.searchBar

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 400
        tableView.sectionHeaderHeight = 40
        tableView.sectionIndexBackgroundColor = UIColor.clear
        tableView.sectionIndexMinimumDisplayRowCount = 15


        array = [words(sectionName: "Ga", coptic: ["Gabriyl", "gaza", "gazovulakion", "gala", "galynyc", "Galile`a", "galileoc", "gamoc", "gar"], english: ["ghabriyēl\n\n(Heb.) - Gabriel", "ghå`zå\n\n(f.) - Treasure, money chest", "ghåzo`filåk`yon\n\n(Gk.) - Treasury", "ghå`lå\n\n(Gk. m.) - Milk", "ghålēnēs\n\n(Gk. f.) - Gentle, calm", "ghålilā`å\n\nGalilee", "ghålilā`os\n\n(adj.) - Galilean", "ghåmos / gåmos\n\n(Gk. m.) - Wedding, marriage", "ghår\n\n(Gk. conj.) - For, because"]),
        words(sectionName: "Ge", coptic: ["geenna", "gene`a", "genecic", "genneoc", "gennyma", "gennycic", "gennytyc", "gennytria", "genoc", "Gewrgioc"], english: ["ge`ā`nå\n\n(Heb.) - Gehenna, Hades", "gene`å\n\n1. (Gk. f.) - Generation\n\n2. (Gk. f.) - New, recent", "genesis\n\n(Gk. f.) - Birth, start, inception", "gennā`os\n\n(Gk. adj.) - Brave, noble, honorable, good", "gennē`må\n\n(Gk. m.) - Offspring, product", "gennē`sis\n\n(Gk. f.) - Birth, generation", "gennē`tēs\n\n(Gk. m.) - Parent, generator", "gennēt`riyā\n\n(Gk. f.) - Parent, generator", "gā`nos\n\n(Gk. m.) - Race, tribe", "ge`ōrgi`yos\n\nGeorge"]),
                 words(sectionName: "Gy", coptic: ["gy"], english: ["gē\n\n(Gk. f.) - Earth, ground, land"]),
                 words(sectionName: "Gn", coptic: ["gnovoc", "gnwmy", "gnwcic"], english: ["ghno`fos\n\n(Gk. m.) - Darkness, gloom", "ghnō`mē\n\n(Gk. f.) - Opinion, thought, judgement", "ghnō`sis\n\n(Gk. f.) - Knowledge"]),
                 words(sectionName: "Go", coptic: ["Golgo;a", "Gomorra", "gonato"], english: ["gholghothå\n\n(Heb. f.) - Calvary, Golgotha", "ghomorrå\n\n(Heb.) - Gomorrah", "ghonå`to\n\n(Gk.) - Knee"]),
                 words(sectionName: "Gr", coptic: ["grammateuc", "grammatiky", "gravy"], english: ["gråmmå`tevs\n\n(Gk. m.) - Scribe, secretary", "gråmmå`tikē\n\n(Gk. f.) - Grammar", "ghrå`fē\n\n(Gk. f.) - Writing, drawing, book"]),
                 words(sectionName: "Gw", coptic: ["Gwg"], english: ["gōg\n\nGog"]),

        ]


    }

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

    // MARK: - Table view data source

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as UITableViewCell!

        cell?.textLabel?.text = array[indexPath.section].coptic[indexPath.row]
        cell?.detailTextLabel?.text = array[indexPath.section].english[indexPath.row]
        cell?.textLabel?.font = UIFont(name:"CS Avva Shenouda", size:30)
        cell?.detailTextLabel?.font = UIFont(name: "Constantia", size:25)
        cell?.textLabel?.numberOfLines = 0
        cell?.detailTextLabel?.numberOfLines = 0
        cell?.textLabel?.textColor = UIColor.black
        cell?.detailTextLabel?.textColor = UIColor.darkGray

        return cell!
    }


    override func numberOfSections(in tableView: UITableView) -> Int {
        return array.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       return array[section].coptic.count

    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return array[section].sectionName

    }

    override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return indexarray
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

    override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
    {
        let header = view as! UITableViewHeaderFooterView
        header.textLabel?.font = UIFont(name: "CS Avva Shenouda", size: 25)!
        header.textLabel?.textColor = UIColor.black
        header.backgroundView?.backgroundColor = UIColor.lightGray

    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Row \(indexPath.row) selected")
    }

    func updateSearchResults(for searchController: UISearchController) {
        if searchController.searchBar.text! == "" {


        } else {


        }

    }


}
Mina Makar
  • 51
  • 10

1 Answers1

1

I try to figure out your problem hope you want the following code to get output

enter image description here

//
//  ViewController.swift
//  Testing
//
//  Created by Jaydeep on 28/10/17.


    import UIKit

    class Gamma: UITableViewController, UISearchBarDelegate, UISearchResultsUpdating,UISearchControllerDelegate {


        struct words {

            var coptic : [String]!
            var english : [String]!
        }

        var array = [words]()
        var filtered = [words]()
        var filtered2 = UITableViewController()



        let searchController = UISearchController(searchResultsController: nil)




        override func viewDidLoad() {
            super.viewDidLoad()


            let defaultTextAttribs = [NSAttributedStringKey.font.rawValue: UIFont.systemFont(ofSize: 17), NSAttributedStringKey.foregroundColor.rawValue:UIColor.black]


            UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = defaultTextAttribs as Any as! [String : Any]


            self.navigationController?.navigationBar.tintColor = UIColor.white


            searchController.searchBar.delegate = self
            searchController.searchResultsUpdater = self
            searchController.hidesNavigationBarDuringPresentation = false
            searchController.dimsBackgroundDuringPresentation = false
            searchController.delegate = self

            self.navigationItem.titleView = searchController.searchBar

            tableView.rowHeight = UITableViewAutomaticDimension
            tableView.estimatedRowHeight = 400
            tableView.sectionHeaderHeight = 40
            tableView.sectionIndexBackgroundColor = UIColor.clear
            tableView.sectionIndexMinimumDisplayRowCount = 15


            array = [words(coptic: ["Gabriyl", "gaza", "gazovulakion", "gala", "galynyc", "Galile`a", "galileoc", "gamoc", "gar"], english:
                ["ghabriyēl \n\n(Heb.) - Gabriel", "ghå`zå\n\n(f.) - Treasure,money chest", "ghåzo`filåk`yon\n\n(Gk.) - Treasury", "ghå`lå\n\n(Gk. m.) - Milk", "ghålēnēs\n\n(Gk. f.) - Gentle, calm", "ghålilā`å\n\nGalilee", "ghålilā`os\n\n(adj.) - Galilean", "ghåmos / gåmos\n\n(Gk. m.) - Wedding, marriage", "ghår\n\n(Gk. conj.) - For, because"]),
                     words(coptic: ["geenna", "gene`a", "genecic", "genneoc", "gennyma", "gennycic", "gennytyc", "gennytria", "genoc", "Gewrgioc"], english: ["ge`ā`nå\n\n(Heb.) - Gehenna, Hades", "gene`å\n\n1. (Gk. f.) - Generation\n\n2. (Gk. f.) - New, recent", "genesis\n\n(Gk. f.) - Birth, start, inception", "gennā`os\n\n(Gk. adj.) - Brave, noble, honorable, good", "gennē`må\n\n(Gk. m.) - Offspring, product", "gennē`sis\n\n(Gk. f.) - Birth, generation", "gennē`tēs\n\n(Gk. m.) - Parent, generator", "gennēt`riyā\n\n(Gk. f.) - Parent, generator", "gā`nos\n\n(Gk. m.) - Race, tribe", "ge`ōrgi`yos\n\nGeorge"]),
                     words( coptic: ["gy"], english: ["gē\n\n(Gk. f.) - Earth, ground, land"]),
                     words(coptic: ["gnovoc", "gnwmy", "gnwcic"], english: ["ghno`fos\n\n(Gk. m.) - Darkness, gloom", "ghnō`mē\n\n(Gk. f.) - Opinion, thought, judgement", "ghnō`sis\n\n(Gk. f.) - Knowledge"]),
                     words(coptic: ["Golgo;a", "Gomorra", "gonato"], english: ["gholghothå\n\n(Heb. f.) - Calvary, Golgotha", "ghomorrå\n\n(Heb.) - Gomorrah", "ghonå`to\n\n(Gk.) - Knee"]),
                     words( coptic: ["grammateuc", "grammatiky", "gravy"], english: ["gråmmå`tevs\n\n(Gk. m.) - Scribe, secretary", "gråmmå`tikē\n\n(Gk. f.) - Grammar", "ghrå`fē\n\n(Gk. f.) - Writing, drawing, book"]),
                     words( coptic: ["Gwg"], english: ["gōg\n\nGog"]),

            ]
            filtered = array


        }
        func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
            searchBar.text = ""
            // Hide the cancel button
            searchBar.showsCancelButton = false
            filtered = array
            tableView.reloadData()
        }
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }

        // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
    if filtered.count > 0

    {
        return filtered.count
    }
    else
    {
        return 0
    }
}
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cellIdentifier = "cell"
            var cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
            if cell == nil
            {
                cell = UITableViewCell(style: UITableViewCellStyle.value2, reuseIdentifier: cellIdentifier)
            }
            cell?.textLabel?.text = filtered[indexPath.section].coptic[indexPath.row]
            cell?.detailTextLabel?.text = filtered[indexPath.section].english[indexPath.row]
            cell?.textLabel?.font = UIFont.systemFont(ofSize: 20)
            cell?.detailTextLabel?.font = UIFont.systemFont(ofSize: 15)
            cell?.textLabel?.numberOfLines = 0
            cell?.detailTextLabel?.numberOfLines = 0
            cell?.textLabel?.textColor = UIColor.black
            cell?.detailTextLabel?.textColor = UIColor.darkGray

            return cell!
        }

        override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return UITableViewAutomaticDimension
        }


        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            if filtered.count > 0
            {
                return filtered[section].coptic.count
            }
            else
            {
            return 0
            }
        }

        override var preferredStatusBarStyle: UIStatusBarStyle {
            return .lightContent
        }

        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            print("Row \(indexPath.row) selected")
        }

        func updateSearchResults(for searchController: UISearchController) {
            // If we haven't typed anything into the search bar then do not filter the results
            if searchController.searchBar.text! == ""
            {
                filtered = array
            }
            else
            {
                filtered.removeAll()
                for  i:Int in 0 ..< array.count
                    {
                        var copticArray:[String] = []
                        var englishArray:[String] = []
                        var tempWord:words = words.init(coptic: [], english: [])


                        let copticCount = array[i].coptic.count
                        for  copticIndex:Int in 0 ..< copticCount
                        {
                            if array[i].coptic[copticIndex].lowercased().contains(searchController.searchBar.text!.lowercased())
                            {

                                copticArray.append(array[i].coptic[copticIndex])
                                englishArray.append(array[i].english[copticIndex])

                            }
                        }

                        tempWord.coptic = copticArray
                        tempWord.english = englishArray
                        if (copticArray.count > 0)
                        {
                            self.filtered.append(tempWord)
                        }
                    }
                tableView.reloadData()

            }
        }


    }
Jaydeep Vyas
  • 4,411
  • 1
  • 18
  • 44
  • I got it to work. Thank you so much. Do you by any chance know how to change the font of the index array? – Mina Makar Oct 28 '17 at 05:13
  • Ok so this code actually works when the cell is set to custom. But when the cell is set to subtitle, which is the format I want, it crashes when I search for a word. Any reason as to why this happens? – Mina Makar Oct 28 '17 at 05:22
  • To be more clear, I want to filter using the coptic string and have it show as the cell textlabel, while also showing the corresponding english string in the detailtextlabel. Is this at all possible? – Mina Makar Oct 28 '17 at 05:28
  • you mean to say if i search "Gal" it only display the section "GA" not "GE" even there is string in "GE" section right?? – Jaydeep Vyas Oct 28 '17 at 05:37
  • I added a picture for reference. So imagine in section "Ga" there are ten words. The coptic and english string for the ten words are listed in alphabetical order. So when the table loads, it writes the Coptic string word on top and the english word underneath it in the cell. I want to be able to filter through the sections to look up a coptic word and have the corresponding english definition to be underneath it. – Mina Makar Oct 28 '17 at 05:45
  • I'm able to filter and have it work the way I want if I don't add sections. But, I want to have the sections visible. I also don't want the search to be section specific but to search the whole array for relevance. ie. if i start searching "a", all words with the letter "a" in all sections should pop up. – Mina Makar Oct 28 '17 at 05:50
  • i updated screen shot do you want that type . ?? let me know if yes – Jaydeep Vyas Oct 28 '17 at 05:54
  • I like that sectioning better in the updated picture but I want the english string definition to appear underneath the word, just like in the picture I posted on top. – Mina Makar Oct 28 '17 at 06:08
  • i cant get get your point could you please post screen shot of your given array with more search results from sections – Jaydeep Vyas Oct 28 '17 at 06:10
  • I updated two photos. One where there is no active search.....without sections. And one where I search using only one letter. I want to filter my code up top to populate the cells in the same manner, but list the appropriate section title on top. – Mina Makar Oct 28 '17 at 06:20
  • Just for reference. The code I am using to get it to work without sections is array = [words(coptic: "", english: ""), words(coptic: "", english: ""), etc.... – Mina Makar Oct 28 '17 at 06:27
  • I think you remove the section array and index array right – Jaydeep Vyas Oct 28 '17 at 06:41
  • Does it make sense now? – Mina Makar Oct 28 '17 at 06:49
  • So is what I'm asking for possible, or should I look for alternative coding for the array? – Mina Makar Oct 28 '17 at 07:10
  • obviously its possible – Jaydeep Vyas Oct 28 '17 at 07:15
  • This works perfectly except when I type a letter that doesn't have a match in the list. If i type the letter "q" the app crashes. – Mina Makar Oct 28 '17 at 07:55
  • That works. I notice though that when I press cancel in the search bar that it doesn't return the array to its normal position but stays on the last search. – Mina Makar Oct 28 '17 at 08:24
  • Quick question. I just noticed that only the first section with "Ga" words shows up. When I search for say the letter "e", it only returns words within the section "Ga" that contain the letter "e". but if I search "Ge", then the words in section "Ge" show up. How can I have all the sections show whenever I search for any random letter? – Mina Makar Oct 28 '17 at 14:58
  • do you by any chance know how to change the input keyboard for the search bar? i want to make a custom one. i tried access the textfield within the searchbar but the app keeps crashing. – Mina Makar Nov 01 '17 at 17:45
  • i have answered your question please see the https://stackoverflow.com/a/47067921/6028575 – Jaydeep Vyas Nov 02 '17 at 05:06
  • Can I trouble you for one more thing. I know that I can filter the array by either letters contained in the tableview or by exact word search. Is it possible to search by both parameters but have exact word search appear at top of list before other letter searches? The tableview I have has thousands of words starting with different letters of the alphabet. – Mina Makar Nov 08 '17 at 00:00
  • you should use `hello dolly".hasPrefix("hello")` method – Jaydeep Vyas Nov 08 '17 at 04:06
  • I considered the .hasPrefix method. It returns the entire list but doesn't actually filter. maybe I'm doing something wrong. – Mina Makar Nov 09 '17 at 03:55
  • i given example in your question try that https://stackoverflow.com/a/47193741/6028575 – Jaydeep Vyas Nov 09 '17 at 04:08