【问题标题】:Reloading TableView using UISegmentedControl in Swift [closed]在 Swift 中使用 UISegmentedControl 重新加载 TableView [关闭]
【发布时间】:2018-08-19 21:06:09
【问题描述】:

我正在创建一个搜索屏幕,您可以在其中选择四个不同的选项。如果选择人员,则人员数组会加载到表格视图单元格中,如果他选择图像,则图像帖子会加载到表格视图中。

我怎样才能实现上面发布的设计?我已经创建了四个不同的单元格和 nib 文件,并且根据在段控制中选择的选项,我必须将这些 nib 文件加载到表格单元格中。

更新 ::::

我在这里更新我已合并到一个文件中的所有代码。

import UIKit
import Alamofire

class SearchViewController: UIViewController , UITableViewDataSource , UITableViewDelegate , UISearchBarDelegate{


var imagepost : ImageSeachPostData!
var imageposts = [ImageSeachPostData]()
var videopost : VideoSeachPostData!
var videoposts = [VideoSeachPostData]()
var statuspost : StatusSearchPostData!
var statusposts = [StatusSearchPostData]()
var penpalpost : PenpalSearchPostData!
var penpalposts = [PenpalSearchPostData]()
var tablearray : NSArray = []



typealias DownloadComplete = () -> ()

@IBOutlet weak var searchTable: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var searchTypeSegmentControl: UISegmentedControl!
override func viewDidLoad() {
    super.viewDidLoad()
    searchTable.dataSource = self
    searchTable.delegate = self
    searchBar.delegate = self
    searchPassed()

}
    @IBAction func onChangeSegment(_ sender: UISegmentedControl)
    {
        self.searchTable.reloadData()
    }


    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {

        view.endEditing(true)
    }

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

        if searchBar.text == nil || searchBar.text == "" {

            searchTable.reloadData()
            view.endEditing(true)

        } else {

            searchPassed()
            searchTable.reloadData()

        }

    }

func searchPassed()
{
    let searchText = "Postpositives" 
    print(searchText)
    var request = URLRequest(url: URL(string: "https://www.example.com/search")!)
    request.httpMethod = "GET"
    let postString = "q=\(searchText)"
    request.httpBody = postString.data(using: .utf8)

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {                                                 // check for fundamental networking error
            print("error=\(String(describing: error))")
            print("cant run")
            return
        }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(String(describing: response))")
            print("\(searchText)")


        }
        else {
            let responseString = String(data: data, encoding: .utf8)
            print("responseString = \(String(describing: responseString))")
   //             func downloadPostData(completed: @escaping DownloadComplete) {
                Alamofire.request("https://www.example.com/api/search?q=\(searchText)").responseJSON { response in
                    let result = response.result
                    if let dict = result.value as? Dictionary<String,AnyObject> {

                        if let successcode = dict["STATUS_CODE"] as? Int {
                            if successcode == 1 {
                                if let postsArray = dict["posts"] as? [Dictionary<String,AnyObject>]
                                {
                                    for obj in postsArray
                                    {
                                        let mediatype = dict["media_type"] as! String?
                                        if mediatype == "image"
                                        {
                                        let imagepost = ImageSeachPostData(postDict: obj)
                                        self.imageposts.append(imagepost)
                                        }
                                        else if mediatype == "video"
                                        {
                                        let videopost = VideoSeachPostData(postDict: obj)
                                        self.videoposts.append(videopost)
                                        }
                                        else if mediatype == "null"
                                        {
                                        let statuspost = StatusSearchPostData(postDict: obj)
                                        self.statusposts.append(statuspost)
                                        }
                                        let penpalpost = PenpalSearchPostData(postDict: obj)
                                        self.penpalposts.append(penpalpost)

                                    }
                                    self.searchTable.reloadData()
                                }
                            }
                        }
                    }
                }
            }



        }
       }
            task.resume()


}

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

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

    let selectedIndex = self.searchTypeSegmentControl.selectedSegmentIndex
    switch selectedIndex
    {
    case 0:
        return penpalposts.count
    case 1:
        return statusposts.count
    case 2:
        return imageposts.count
    case 3:
        return videoposts.count

    default:
        return 0
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let selectedIndex = self.searchTypeSegmentControl.selectedSegmentIndex
    switch selectedIndex
    {
    case 0:
        return tableView.dequeueReusableCell(withIdentifier: "penpalSearchReuse", for: indexPath)
    case 1:
        return tableView.dequeueReusableCell(withIdentifier: "statusSearchReuse", for: indexPath)

    case 2:
        return tableView.dequeueReusableCell(withIdentifier: "imageSearchReuse", for: indexPath)
    case 3:
        return tableView.dequeueReusableCell(withIdentifier: "videoSearchReuse", for: indexPath)

    default:
        return UITableViewCell()
}
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return 420
}


}

【问题讨论】:

  • 到目前为止你尝试过什么?你可以使用 UISearchController 实现你想要的。查找 searchBar 的 scopedButtonTitles 属性
  • 上传所有代码并不会突然变得不那么宽泛,只会让阅读时间更长!

标签: ios swift search uisegmentedcontrol


【解决方案1】:

使用UISegmentedControlselectedSegmentIndex属性根据选择的段处理UITableViewDataSource

示例:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    let selectedIndex = self.segmentedControl.selectedSegmentIndex
    switch selectedIndex
    {
    case 0:
        return peopleArray.count
    case 1:
        return imagesArray.count
    //Add other cases here
    default:
        return 0
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let selectedIndex = self.segmentedControl.selectedSegmentIndex
    switch selectedIndex
    {
    case 0:
        return tableView.dequeueReusableCell(withIdentifier: "peopleCell", for: indexPath) //Do your custom handling whatever required.
    case 1:
        return tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath)
    //Add other cases here
    default:
        return UITableViewCell()
    }
}

@IBAction func onChangeSegment(_ sender: UISegmentedControl)
{
    self.tableView.reloadData()
}

【讨论】:

  • nope .. 试过这个 .. 抛出错误:由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'-[WorkingFeed2.SearchViewController indexChangedforsegmentedControl:]:无法识别的选择器发送到实例 0x7fb5a450a310'跨度>
  • 您是否已将 segmentedControl valueChanged 操作连接到 @IBAction onChangeSegment?
  • o 是的,我错误地评论了操作命令.. 现在它可以工作了.. 但仍然没有加载数据.. 我想我在从搜索栏获取数据时出错了
  • 你连接tableView数据源了吗?
  • 是的,它的意思是“无法将标识符为 penpalSearchReuse 的单元格出列 - 必须为标识符注册一个 nib 或一个类,或者在情节提要中连接一个原型单元格”
【解决方案2】:

非常简单制作一个表格数组,即tableView的公共数据源,并创建4个数组,其中有实际数据。现在在每个段点击调用像

点击第一段

tableArray = segment_1_Array
tableView.reloadData()

点击第二段

tableArray = segment_2_Array
tableView.reloadData()

等等..

cellForRowDelegate Method中会有switch声明

let modelObj = tableArray[indexpath.row]
let cellID = ""

switch modelObj {
case _ as CellModelType1 : cellID = "CellType1Identifier"
case _ as CellModelType2 : cellID = "CellType2Identifier"
case _ as CellModelType3 : cellID = "CellType3Identifier"
case _ as CellModelType4 : cellID = "CellType4Identifier"

}

let cell = tableView.dequeueReusableCell(withIdentifier: cellID) as! TableCell
return cell

注意

1. TableCell 将是超类,如果这个类,所有 4 个单元格都将是子类

2。 CellModelType1、CellModelType2、CellModelType3、CellModelType4

是不同的细胞模型例如可以是

PeopleCellModelPostsCellModelImagesCellModelVideoCellModel

因此您不必管理行数

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {    
    return tableArray.count
}

【讨论】:

  • 我应该在 cellforrowat 中传递什么?
  • 代码更新:)
【解决方案3】:

你可以使用这样的结构:

let people = ["pe1", "pe2", "pe3"]
let post = ["po1", "po2", "po3"]
let images = ["im1", "im2", "im3"]
let video = ["vi1", "vi2", "vi3"]

var selectedDataSource: [String] {
    switch segmentedControl.selectedSegmentIndex {
    case 0: return people
    case 1: return post
    case 2: return images
    case 3: return video
    default: return []
    }
}

然后您可以在所有 tableview 数据源方法中使用selectedDataSource。当然,当用户更改选择时,您必须重新加载 tableview。

【讨论】:

    【解决方案4】:

    您需要创建一个 IBAction,它会在 valueChanged 事件上触发:

    @IBAction func segmentChange(_ sender: UISegmentedControl) {
        var nibToLoad = UINib()
        switch sender.selectedSegmentIndex {
        case 0:
            nibToLoad = UINib(nibName: "peopleNib", bundle: Bundle.main)
            tableViewDataSourceArray = PeopleArray
        case 1:
            nibToLoad = UINib(nibName: "postNib", bundle: Bundle.main)
            tableViewDataSourceArray = PostArray
        case 2:
            nibToLoad = UINib(nibName: "imageNib", bundle: Bundle.main)
            tableViewDataSourceArray = ImageArray
        case 3:
            nibToLoad = UINib(nibName: "videoNib", bundle: Bundle.main)
            tableViewDataSourceArray = VideoArray
        default:
            //default action
        }
        tableView.register(nibToLoad, forCellReuseIdentifier: "identifier")
        tableView.reloadData()
    }
    

    然后,您将确保您的所有 UITableViewDelegateUITableViewDataSource 方法都在使用您的 tableViewDataSourceArray(无论您调用哪个变量)。

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 2021-05-28
      • 2017-11-14
      • 1970-01-01
      • 1970-01-01
      • 2014-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多