在 Swift 中使用 UISegmentedControl 重新加载 TableView
Reloading TableView using UISegmentedControl in Swift
我正在创建一个搜索屏幕,您可以在其中 select 四个不同的选项。如果一个 select 人,那么人物数组将加载到 table 视图单元格中,如果他是 select 人,那么图像帖子将加载到 table 视图中。
如何实现上面的设计?我已经创建了四个不同的单元格和 nib 文件,并且基于段控制中的 selected 选项,我必须将这些 nib 文件加载到 table 单元格中。
更新:::
我正在更新我合并到一个文件中的所有代码。
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
}
}
非常简单 创建一个 table 数组,即 table 的公共数据源 查看并创建 4 个数组,其中包含实际数据。现在在每个段上点击调用
点击第一段
tableArray = segment_1_Array
tableView.reloadData()
点击第二段
tableArray = segment_2_Array
tableView.reloadData()
等等..
在cellForRow
委托方法中会有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 将是超类,如果 class
所有 4 个单元格都将是子 class
2。 CellModelType1、CellModelType2、CellModelType3、CellModelType4
是不同的cell型号比如可以
PeopleCellModel、PostsCellModel、ImagesCellModel 和 VideoCellModel
因此您不必管理行数
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableArray.count
}
使用UISegmentedControl
的selectedSegmentIndex
属性根据所选段处理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()
}
您可以使用这样的结构:
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
。当然,当用户更改选择时,您必须重新加载表格视图。
您需要创建一个将在 valueChanged 事件上触发的 IBAction:
@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()
}
然后您将确保所有 UITableViewDelegate
和 UITableViewDataSource
方法都使用您的 tableViewDataSourceArray
(无论您调用该变量)。
我正在创建一个搜索屏幕,您可以在其中 select 四个不同的选项。如果一个 select 人,那么人物数组将加载到 table 视图单元格中,如果他是 select 人,那么图像帖子将加载到 table 视图中。
如何实现上面的设计?我已经创建了四个不同的单元格和 nib 文件,并且基于段控制中的 selected 选项,我必须将这些 nib 文件加载到 table 单元格中。
更新:::
我正在更新我合并到一个文件中的所有代码。
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
}
}
非常简单 创建一个 table 数组,即 table 的公共数据源 查看并创建 4 个数组,其中包含实际数据。现在在每个段上点击调用
点击第一段
tableArray = segment_1_Array
tableView.reloadData()
点击第二段
tableArray = segment_2_Array
tableView.reloadData()
等等..
在cellForRow
委托方法中会有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 将是超类,如果 class
所有 4 个单元格都将是子 class2。 CellModelType1、CellModelType2、CellModelType3、CellModelType4
是不同的cell型号比如可以
PeopleCellModel、PostsCellModel、ImagesCellModel 和 VideoCellModel
因此您不必管理行数
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableArray.count
}
使用UISegmentedControl
的selectedSegmentIndex
属性根据所选段处理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()
}
您可以使用这样的结构:
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
。当然,当用户更改选择时,您必须重新加载表格视图。
您需要创建一个将在 valueChanged 事件上触发的 IBAction:
@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()
}
然后您将确保所有 UITableViewDelegate
和 UITableViewDataSource
方法都使用您的 tableViewDataSourceArray
(无论您调用该变量)。