UISearch 在 JSON api UITableView 中不工作
UISearch is not Working in JSON api UITable View
全部
我正在尝试开发一个应用程序。现在我需要使用 UISearch View 搜索视频列表。
这是我的代码。我可以看到搜索栏,但它不工作。
导入 UIKit
导入 Google 移动广告
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, GADInterstitialDelegate, UIAlertViewDelegate, UISearchBarDelegate {
@IBOutlet weak var tblVideos: UITableView!
@IBOutlet weak var banner3: GADBannerView!
var interstitial: GADInterstitial!
@IBOutlet weak var viewWait: UIView!
var channelsDataArray: Array<Dictionary<String, Any>> = []
var apikey = ""
var selectedVideoIndex: Int!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if connectedToNetwork() == true {
tblVideos.delegate = self
tblVideos.dataSource = self
print("Google Mobile Ads SDK version: " + GADRequest.sdkVersion())
banner3.adUnitID = ""
banner3.rootViewController = self
banner3.load(GADRequest())
getChannelDetails(false)
loadInterstitial()
searchBar()
}
else {
let controller = UIAlertController(title: "No Internet Detected", message: "This app requires an Internet connection", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
controller.addAction(ok)
controller.addAction(cancel)
present(controller, animated: true, completion: nil)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func searchBar() {
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 50))
searchBar.delegate = self
searchBar.showsScopeBar = true
searchBar.tintColor = UIColor.lightGray
self.tblVideos.tableHeaderView = searchBar
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
//do something
getChannelDetails(false)
}
else {
channelsDataArray = channelsDataArray.filter({([=12=]["title"] as! String).contains(searchText)})
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let playerViewController = segue.destination as? PlayerViewController {
playerViewController.videoID = channelsDataArray[selectedVideoIndex]["videoId"] as! String
}
}
// MARK: UITableView method implementation
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return channelsDataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell!
cell = tableView.dequeueReusableCell(withIdentifier: "idCellChannel", for: indexPath)
let channelTitleLabel = cell.viewWithTag(10) as! UILabel
let thumbnailImageView = cell.viewWithTag(12) as! UIImageView
let channelDetails = channelsDataArray[indexPath.row]
channelTitleLabel.text = channelDetails["title"] as? String
thumbnailImageView.image = UIImage(data: try! Data(contentsOf: URL(string: (channelDetails["url"] as? String)!)!))
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 350.0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedVideoIndex = indexPath.row
performSegue(withIdentifier: "idSeguePlayer", sender: self)
if (interstitial!.isReady) {
interstitial!.present(fromRootViewController: self)
}
loadInterstitial()
}
// MARK: UITextFieldDelegate method implementation
// MARK: Custom method implementation
func performGetRequest(_ targetURL: URL!, completion: @escaping (_ data: Data?, _ HTTPStatusCode: Int, _ error: Error?) -> Void) {
var request = URLRequest(url: targetURL)
request.httpMethod = "GET"
let sessionConfiguration = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfiguration)
let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in
DispatchQueue.main.async(execute: { () -> Void in
completion(data, (response as! HTTPURLResponse).statusCode, error)
})
} )
task.resume()
}
func getChannelDetails(_ useChannelIDParam: Bool) {
var urlString: String!
if !useChannelIDParam {
urlString = "https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&type=video&q=mufti+amir+hamza&maxResults=50&key=apikey"
}
let targetURL = URL(string: urlString)
performGetRequest(targetURL, completion: { (data, HTTPStatusCode, error) -> Void in
if HTTPStatusCode == 200 && error == nil {
do {
if let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:Any] {
if let items = resultsDict["items"] as? [[String:Any]] {
for item in items {
var desiredValues = [String:Any]()
//get the videoId
if let id = item["id"] as? [String:Any], let videoId = id["videoId"] as? String{
desiredValues["videoId"] = videoId
}
//get title and thumbnail from snippet
if let snippet = item["snippet"] as? [String:Any] {
if let title = snippet["title"] {
desiredValues["title"] = title
}
if let thumbanail = snippet["thumbnails"] as? [String:Any], let highValues = thumbanail["high"] as? [String:Any], let url = highValues["url"] as? String {
desiredValues["url"] = url
}
}
self.channelsDataArray.append(desiredValues)
}
DispatchQueue.main.async {
self.tblVideos.reloadData()
}
}
}
}
catch (let error){
print("Error while parsing data: \(error.localizedDescription)")
}
}
self.viewWait.isHidden = true
})
}
//inter
fileprivate func loadInterstitial() {
interstitial = GADInterstitial(adUnitID: "")
interstitial!.delegate = self
// Request test ads on devices you specify. Your test device ID is printed to the console when
// an ad request is made.
interstitial!.load(GADRequest())
}
// MARK: GADInterstitialDelegate implementation
func interstitialDidFailToReceiveAdWithError (
_ interstitial: GADInterstitial,
error: GADRequestError) {
print("interstitialDidFailToReceiveAdWithError: %@" + error.localizedDescription)
}
func interstitialDidDismissScreen (_ interstitial: GADInterstitial) {
print("interstitialDidDismissScreen")
}
}
我现在只需要将我的列表过滤为标题。能帮我解决一下吗?
您需要为 filteredArray 声明一个 var 以保留包含所有元素的原始数组
像这样
var filteredChannelsDataArray : Array<Dictionary<String, Any>> = []
您还需要在 getChannelDetails
方法中的 self.channelsDataArray.append(desiredValues)
之后添加此行
self.filteredChannelsDataArray = channelsDataArray
试试这个
替换这个
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
//do something
getChannelDetails(false)
}
else {
channelsDataArray = channelsDataArray.filter({ (alldata) -> Bool in
return true
})
}
}
据此
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
//do something
getChannelDetails(false)
self.filteredChannelsDataArray = channelsDataArray
self.tableView.reloadData()
}
else {
self.filteredChannelsDataArray = channelsDataArray.filter({([=13=]["title"] as! String).contains(searchText)})
self.tableView.reloadData()
}
}
您还需要对 UITableViewDataSource
方法进行一些更改
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.filteredChannelsDataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell!
cell = tableView.dequeueReusableCell(withIdentifier: "idCellChannel", for: indexPath)
let channelTitleLabel = cell.viewWithTag(10) as! UILabel
let thumbnailImageView = cell.viewWithTag(12) as! UIImageView
let channelDetails = self.filteredChannelsDataArray[indexPath.row]
channelTitleLabel.text = channelDetails["title"] as? String
thumbnailImageView.image = UIImage(data: try! Data(contentsOf: URL(string: (channelDetails["url"] as? String)!)!))
return cell
}
您可以尝试使用此代码:self.tblVideos.reloadData()
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
//do something
getChannelDetails(false)
}
else {
channelsDataArray = channelsDataArray.filter({([=10=]["title"] as! String).contains(searchText)})
self.tblVideos.reloadData()
}
}
全部
我正在尝试开发一个应用程序。现在我需要使用 UISearch View 搜索视频列表。
这是我的代码。我可以看到搜索栏,但它不工作。
导入 UIKit 导入 Google 移动广告
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, GADInterstitialDelegate, UIAlertViewDelegate, UISearchBarDelegate {
@IBOutlet weak var tblVideos: UITableView!
@IBOutlet weak var banner3: GADBannerView!
var interstitial: GADInterstitial!
@IBOutlet weak var viewWait: UIView!
var channelsDataArray: Array<Dictionary<String, Any>> = []
var apikey = ""
var selectedVideoIndex: Int!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if connectedToNetwork() == true {
tblVideos.delegate = self
tblVideos.dataSource = self
print("Google Mobile Ads SDK version: " + GADRequest.sdkVersion())
banner3.adUnitID = ""
banner3.rootViewController = self
banner3.load(GADRequest())
getChannelDetails(false)
loadInterstitial()
searchBar()
}
else {
let controller = UIAlertController(title: "No Internet Detected", message: "This app requires an Internet connection", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
controller.addAction(ok)
controller.addAction(cancel)
present(controller, animated: true, completion: nil)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func searchBar() {
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 50))
searchBar.delegate = self
searchBar.showsScopeBar = true
searchBar.tintColor = UIColor.lightGray
self.tblVideos.tableHeaderView = searchBar
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
//do something
getChannelDetails(false)
}
else {
channelsDataArray = channelsDataArray.filter({([=12=]["title"] as! String).contains(searchText)})
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let playerViewController = segue.destination as? PlayerViewController {
playerViewController.videoID = channelsDataArray[selectedVideoIndex]["videoId"] as! String
}
}
// MARK: UITableView method implementation
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return channelsDataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell!
cell = tableView.dequeueReusableCell(withIdentifier: "idCellChannel", for: indexPath)
let channelTitleLabel = cell.viewWithTag(10) as! UILabel
let thumbnailImageView = cell.viewWithTag(12) as! UIImageView
let channelDetails = channelsDataArray[indexPath.row]
channelTitleLabel.text = channelDetails["title"] as? String
thumbnailImageView.image = UIImage(data: try! Data(contentsOf: URL(string: (channelDetails["url"] as? String)!)!))
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 350.0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedVideoIndex = indexPath.row
performSegue(withIdentifier: "idSeguePlayer", sender: self)
if (interstitial!.isReady) {
interstitial!.present(fromRootViewController: self)
}
loadInterstitial()
}
// MARK: UITextFieldDelegate method implementation
// MARK: Custom method implementation
func performGetRequest(_ targetURL: URL!, completion: @escaping (_ data: Data?, _ HTTPStatusCode: Int, _ error: Error?) -> Void) {
var request = URLRequest(url: targetURL)
request.httpMethod = "GET"
let sessionConfiguration = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfiguration)
let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in
DispatchQueue.main.async(execute: { () -> Void in
completion(data, (response as! HTTPURLResponse).statusCode, error)
})
} )
task.resume()
}
func getChannelDetails(_ useChannelIDParam: Bool) {
var urlString: String!
if !useChannelIDParam {
urlString = "https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&type=video&q=mufti+amir+hamza&maxResults=50&key=apikey"
}
let targetURL = URL(string: urlString)
performGetRequest(targetURL, completion: { (data, HTTPStatusCode, error) -> Void in
if HTTPStatusCode == 200 && error == nil {
do {
if let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:Any] {
if let items = resultsDict["items"] as? [[String:Any]] {
for item in items {
var desiredValues = [String:Any]()
//get the videoId
if let id = item["id"] as? [String:Any], let videoId = id["videoId"] as? String{
desiredValues["videoId"] = videoId
}
//get title and thumbnail from snippet
if let snippet = item["snippet"] as? [String:Any] {
if let title = snippet["title"] {
desiredValues["title"] = title
}
if let thumbanail = snippet["thumbnails"] as? [String:Any], let highValues = thumbanail["high"] as? [String:Any], let url = highValues["url"] as? String {
desiredValues["url"] = url
}
}
self.channelsDataArray.append(desiredValues)
}
DispatchQueue.main.async {
self.tblVideos.reloadData()
}
}
}
}
catch (let error){
print("Error while parsing data: \(error.localizedDescription)")
}
}
self.viewWait.isHidden = true
})
}
//inter
fileprivate func loadInterstitial() {
interstitial = GADInterstitial(adUnitID: "")
interstitial!.delegate = self
// Request test ads on devices you specify. Your test device ID is printed to the console when
// an ad request is made.
interstitial!.load(GADRequest())
}
// MARK: GADInterstitialDelegate implementation
func interstitialDidFailToReceiveAdWithError (
_ interstitial: GADInterstitial,
error: GADRequestError) {
print("interstitialDidFailToReceiveAdWithError: %@" + error.localizedDescription)
}
func interstitialDidDismissScreen (_ interstitial: GADInterstitial) {
print("interstitialDidDismissScreen")
}
}
我现在只需要将我的列表过滤为标题。能帮我解决一下吗?
您需要为 filteredArray 声明一个 var 以保留包含所有元素的原始数组
像这样
var filteredChannelsDataArray : Array<Dictionary<String, Any>> = []
您还需要在 getChannelDetails
方法中的 self.channelsDataArray.append(desiredValues)
之后添加此行
self.filteredChannelsDataArray = channelsDataArray
试试这个
替换这个
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
//do something
getChannelDetails(false)
}
else {
channelsDataArray = channelsDataArray.filter({ (alldata) -> Bool in
return true
})
}
}
据此
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
//do something
getChannelDetails(false)
self.filteredChannelsDataArray = channelsDataArray
self.tableView.reloadData()
}
else {
self.filteredChannelsDataArray = channelsDataArray.filter({([=13=]["title"] as! String).contains(searchText)})
self.tableView.reloadData()
}
}
您还需要对 UITableViewDataSource
方法进行一些更改
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.filteredChannelsDataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell!
cell = tableView.dequeueReusableCell(withIdentifier: "idCellChannel", for: indexPath)
let channelTitleLabel = cell.viewWithTag(10) as! UILabel
let thumbnailImageView = cell.viewWithTag(12) as! UIImageView
let channelDetails = self.filteredChannelsDataArray[indexPath.row]
channelTitleLabel.text = channelDetails["title"] as? String
thumbnailImageView.image = UIImage(data: try! Data(contentsOf: URL(string: (channelDetails["url"] as? String)!)!))
return cell
}
您可以尝试使用此代码:self.tblVideos.reloadData()
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
//do something
getChannelDetails(false)
}
else {
channelsDataArray = channelsDataArray.filter({([=10=]["title"] as! String).contains(searchText)})
self.tblVideos.reloadData()
}
}