I want to add a search bar in my tableview which is populated with data from Core Data. Below is parts of code from my TableViewController. How do I begin implementing the searchbar function after placing one on the tableview?
let managedObjectContext =
(UIApplication.sharedApplication().delegate
as! AppDelegate).managedObjectContext
var fetchedLastName = [String]()
var fetchedFirstName = [String]()
var fetchedImage = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reloadData:",name:"load", object: nil)
let entityDescription =
NSEntityDescription.entityForName("Faculty",
inManagedObjectContext: managedObjectContext)
let request = NSFetchRequest()
request.entity = entityDescription
do{
let objects = try managedObjectContext.executeFetchRequest(request)
let results = objects
if results.count > 0 {
for var i = 0; i < results.count; i += 1{
let match = results[i] as! NSManagedObject
fetchedLastName.append((match.valueForKey("lastname") as? String)!)
fetchedFirstName.append((match.valueForKey("firstname") as? String)!)
let image = match.valueForKey("image") as! NSData
fetchedImage.append(UIImage(data: image)!)
}
} else {
}
}
catch{}
}
func reloadData(notification: NSNotification){
fetchedLastName.removeAll()
fetchedFirstName.removeAll()
fetchedImage.removeAll()
let entityDescription =
NSEntityDescription.entityForName("Faculty",
inManagedObjectContext: managedObjectContext)
let request = NSFetchRequest()
request.entity = entityDescription
do{
let objects = try managedObjectContext.executeFetchRequest(request)
let results = objects
if results.count > 0 {
for var i = 0; i < results.count; i += 1{
let match = results[i] as! NSManagedObject
fetchedLastName.append((match.valueForKey("lastname") as? String)!)
fetchedFirstName.append((match.valueForKey("firstname") as? String)!)
let image = match.valueForKey("image") as! NSData
fetchedImage.append(UIImage(data: image)!)
}
} else {
}
}
catch{}
self.tableView.reloadData()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TEACH", forIndexPath: indexPath) as! TEACHTableViewCell
let row = indexPath.row
print(fetchedFirstName)
cell.facultyName.text = fetchedLastName[row] + ", " + fetchedFirstName[row]
cell.facultyImage.image = fetchedImage[row]
return cell
}
}
Try this code all tested:
//
// TEACHTableViewController.swift
// TEACH
//
// Created by ICST340.N1 on 9/29/15.
// Copyright © 2015 IyoTugs. All rights reserved.
//
import UIKit
import CoreData
class TEACHTableViewController: UITableViewController, UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating {
var searchController = UISearchController()
var filteredTableData = [[String: AnyObject?]]()
var tableData = [[String: AnyObject?]]()
let managedObjectContext =
(UIApplication.sharedApplication().delegate
as! AppDelegate).managedObjectContext
var fetchedLastName = [String]()
var fetchedFirstName = [String]()
var fetchedImage = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
//setup search controller
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.delegate = self
tableView.tableHeaderView = searchController.searchBar
definesPresentationContext = true
searchController.searchBar.sizeToFit()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reloadData:",name:"load", object: nil)
let entityDescription =
NSEntityDescription.entityForName("Faculty",
inManagedObjectContext: managedObjectContext)
let request = NSFetchRequest()
request.entity = entityDescription
do{
let objects = try managedObjectContext.executeFetchRequest(request)
let results = objects
if results.count > 0 {
for var i = 0; i < results.count; i += 1{
let match = results[i] as! NSManagedObject
fetchedLastName.append((match.valueForKey("lastname") as? String)!)
fetchedFirstName.append((match.valueForKey("firstname") as? String)!)
//added this is convert the image
let image = match.valueForKey("image") as! NSData
let realImage = UIImage(data: image)!
fetchedImage.append(UIImage(data: image)!)
tableData.append(["firstName" : match.valueForKey("firstname"), "lastName" : match.valueForKey("firstname"), "image" : realImage])
}
} else {
}
}
catch{}
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
func reloadData(notification: NSNotification){
fetchedLastName.removeAll()
fetchedFirstName.removeAll()
//Added this to remove all images
fetchedImage.removeAll()
tableData.removeAll()
let entityDescription =
NSEntityDescription.entityForName("Faculty",
inManagedObjectContext: managedObjectContext)
let request = NSFetchRequest()
request.entity = entityDescription
do{
let objects = try managedObjectContext.executeFetchRequest(request)
let results = objects
if results.count > 0 {
for var i = 0; i < results.count; i += 1{
let match = results[i] as! NSManagedObject
fetchedLastName.append((match.valueForKey("lastname") as? String)!)
fetchedFirstName.append((match.valueForKey("firstname") as? String)!)
//added this is convert the image
let image = match.valueForKey("image") as! NSData
let realImage = UIImage(data: image)!
fetchedImage.append(UIImage(data: image)!)
tableData.append(["firstName" : match.valueForKey("firstname"), "lastName" : match.valueForKey("firstname"), "image" : realImage])
}
} else {
}
}
catch{}
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if searchController.active {
return filteredTableData.count
} else {
return fetchedLastName.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TEACH", forIndexPath: indexPath) as! TEACHTableViewCell
if searchController.active {
let row = indexPath.row
print(fetchedFirstName)
let firstName = filteredTableData[row]["firstName"] as! String
let lastName = filteredTableData[row]["lastName"] as! String
let image = filteredTableData[row]["image"] as! UIImage
cell.facultyName.text = lastName + ", " + firstName
cell.facultyImage.image = image
} else {
let row = indexPath.row
print(fetchedFirstName)
cell.facultyName.text = fetchedLastName[row] + ", " + fetchedFirstName[row]
cell.facultyImage.image = fetchedImage[row]
}
return cell
}
func filterContentForSearchText(searchText: String) {
for singleTableData in tableData {
let firstname = singleTableData["firstName"] as! String
let lastname = singleTableData["lastName"] as! String
let image = singleTableData["image"] as! UIImage
print(firstname)
print(lastname)
if searchText != "" {
if (firstname.rangeOfString(searchText) != nil) {
filteredTableData.append(["firstName" : firstname, "lastName" : lastname, "image" : image])
} else if (lastname.rangeOfString(searchText) != nil) {
filteredTableData.append(["firstName" : firstname, "lastName" : lastname, "image" : image])
}
} else {
filteredTableData.append(["firstName" : firstname, "lastName" : lastname, "image" : image])
}
}
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
filteredTableData.removeAll()
filterContentForSearchText(searchController.searchBar.text!)
tableView.reloadData()
}
}
Related
I am pushing data which is an array of strings to a tableview controller. These strings are "uid's" which are users in my database. With this array I make a call to firebase to extract all users and then do a match to the uid's. I am getting the correct data, yet I print out everything to make sure when the data is available and the data is available only after the tableview cell loads which causes the data to be nil causing a crash or just empty data. How can I make the data load first and then the cell so the data is available for display?
I've created functions for the data and now I have it in my viewDidLoad. Also, you'll see I have tried adding the firebase call into the Cell setup but of course that does not work.
Array of strings
var data = [String]()
viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
Database.database().reference().child("Businesses").observe(.value, with: { snapshot in
if snapshot.exists() {
self.businessUID = snapshot.value as? NSDictionary
if let dict = snapshot.value as? NSDictionary {
for item in dict {
let json = JSON(item.value)
let businessUid = json["uid"].stringValue
for uid in self.data {
if uid == businessUid {
let customerValue = self.businessUID?[uid]
self.businessDictionary = customerValue as! NSDictionary
print(self.businessDictionary)
print("Just printed the business dictionary")
}
}
}
}
} else {
print("does not exist")
}
})
}
Tableview Cell
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomerViewsSelectedBusinessesCell
print(self.businessDictionary)
print("Print the dictionary here to check the values")
let businessValues = self.businessDictionary
let uid = self.data.description
print(businessValues)
print("printed the business values")
if let dict = businessValues {
for item in dict {
let json = JSON(item.value)
let businessUid = json["uid"].stringValue
for uid in self.data {
if uid == businessUid {
let customerValue = self.businessUID?[uid]
self.businessData = customerValue as? NSDictionary
print(self.businessData)
print("Printing matching the uid values")
}
}
}
}
cell.businessName.text = businessData?["businessName"] as? String
cell.businessStreet.text = businessData?["businessStreet"] as? String
cell.businessCity.text = businessData?["businessCity"] as? String
cell.businessState.text = businessData?["businessState"] as? String
let businessProfilePicture = businessData?["profPicString"] as? String
if (businessProfilePicture!.characters.count) > 0 {
let url = URL(string: (businessProfilePicture!))
DispatchQueue.global().async {
let data = try? Data(contentsOf: url!)
DispatchQueue.main.async {
let image = UIImage(data: data!)?.potter_circle
cell.profileImage.contentMode = UIView.ContentMode.scaleAspectFill
cell.profileImage.image = image
}
}
} else {
let image = UIImage(named: "default")?.potter_circle
cell.profileImage.contentMode = UIView.ContentMode.scaleAspectFill
cell.profileImage.image = image
}
return cell
}
Here is my solution. Got it to work. Appened and used "usersArray" to get and display the data.
var data = [String]()
var usersArray = [NSDictionary?]()
override func viewDidLoad() {
super.viewDidLoad()
Database.database().reference().child("Businesses").observe(.value, with: { snapshot in
if snapshot.exists() {
self.businessUID = snapshot.value as? NSDictionary
if let dict = snapshot.value as? NSDictionary {
for item in dict {
let json = JSON(item.value)
let businessUid = json["uid"].stringValue
for uid in self.data {
if uid == businessUid {
let customerValue = self.businessUID?[uid]
self.usersArray.append(customerValue as! NSDictionary)
self.followUsersTableView.reloadData()
}
}
}
}
} else {
print("does not exist")
}
})
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.usersArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomerViewsSelectedBusinessesCell
let user : NSDictionary?
user = self.usersArray[indexPath.row]
cell.businessName.text = String(user?["businessName"] as! String)
cell.businessStreet.text = String(user?["businessStreet"] as! String)
cell.businessCity.text = String(user?["businessCity"] as! String)
cell.businessState.text = String(user?["businessState"] as! String)
let businessProfilePicture = String(user?["profPicString"] as! String)
if (businessProfilePicture.characters.count) > 0 {
let url = URL(string: (businessProfilePicture))
DispatchQueue.global().async {
let data = try? Data(contentsOf: url!)
DispatchQueue.main.async {
let image = UIImage(data: data!)?.potter_circle
cell.profileImage.contentMode = UIView.ContentMode.scaleAspectFill
cell.profileImage.image = image
}
}
} else {
let image = UIImage(named: "default")?.potter_circle
cell.profileImage.contentMode = UIView.ContentMode.scaleAspectFill
cell.profileImage.image = image
}
return cell
}
I'm making an app that parses JSON data & populates a tableview. In this app i want to make a SearchBar to search the id's. Everything is fine with parsing and populating the tableview but I am having problem with the searching. When I run the app I am gettin the following error: terminating with uncaught exception of type NSException
I have two arrays, first one is the main one and the other one is filtered one.
Requirement: I want to search array by "DesenNo" which i declared in my model.
Here are my codes:
ViewController:
import UIKit
import Foundation
import os.log
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating, HomeModelProtocol {
//Properties
var feedItems: NSArray = NSArray()
var detailViewController: detailsVC? = nil
var searchActive : Bool = false
var filteredData:[String] = []
var resultSearchController:UISearchController!
#IBOutlet weak var listTableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
resultSearchController = UISearchController(searchResultsController: nil)
resultSearchController.searchResultsUpdater = self
resultSearchController.hidesNavigationBarDuringPresentation = false
resultSearchController.dimsBackgroundDuringPresentation = false
resultSearchController.searchBar.searchBarStyle = UISearchBarStyle.prominent
resultSearchController.searchBar.sizeToFit()
self.listTableView.tableHeaderView = resultSearchController.searchBar
self.listTableView.dataSource = self
let homeModel = HomeModel()
homeModel.delegate = self
homeModel.downloadItems()
}
func itemsDownloaded(items: NSArray) {
feedItems = items
self.listTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if resultSearchController.isActive {
return filteredData.count
}
else {
return feedItems.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Retrieve cell
let cellIdentifier: String = "BasicCell"
let myCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! MyTableCell
// Get the location to be shown
// Get references to labels of cell
//Label1
if resultSearchController.isActive {
let item: LocationModel = feedItems[indexPath.row] as! LocationModel
let desenNoToString = item.DesenNo
let desenString = "\(desenNoToString)"
let regex = try! NSRegularExpression(pattern:"\"(.*)\"")
if let match = regex.firstMatch(
in: desenString, range:NSMakeRange(0,desenString.utf16.count)) {
let result = (desenString as NSString).substring(with: match.range(at:1))
myCell.label1!.text = result
}
//Label2
let dolarToString = item.Dolar
let dolarString = "\(dolarToString)"
if let match = regex.firstMatch(
in: dolarString, range:NSMakeRange(0,dolarString.utf16.count)) {
let result = (dolarString as NSString).substring(with: match.range(at:1))
myCell.label2!.text = result
}
//Label3
let zeminToString = item.Zemin
let zeminString = "\(zeminToString)"
if let match = regex.firstMatch(
in: zeminString, range:NSMakeRange(0,zeminString.utf16.count)) {
let result = (zeminString as NSString).substring(with: match.range(at:1))
myCell.label3!.text = result
}
//Label4
let renkToString = item.Renk
let renkString = "\(renkToString)"
if let match = regex.firstMatch(
in: renkString, range:NSMakeRange(0,renkString.utf16.count)) {
let result = (renkString as NSString).substring(with: match.range(at:1))
myCell.label4!.text = result
}
//Label5
let enToString = item.En
let enString = "\(enToString)"
if let match = regex.firstMatch(
in: enString, range:NSMakeRange(0,enString.utf16.count)) {
let result = (enString as NSString).substring(with: match.range(at:1))
myCell.label5!.text = result
}
//Label6
let euroToString = item.Euro
let euroString = "\(euroToString)"
if let match = regex.firstMatch(
in: euroString, range:NSMakeRange(0,euroString.utf16.count)) {
let result = (euroString as NSString).substring(with: match.range(at:1))
myCell.label6!.text = result
}
}else {
let item: LocationModel = feedItems[indexPath.row] as! LocationModel
let desenNoToString = item.DesenNo
let desenString = "\(desenNoToString)"
let regex = try! NSRegularExpression(pattern:"\"(.*)\"")
if let match = regex.firstMatch(
in: desenString, range:NSMakeRange(0,desenString.utf16.count)) {
let result = (desenString as NSString).substring(with: match.range(at:1))
myCell.label1!.text = result
}
//Label2
let dolarToString = item.Dolar
let dolarString = "\(dolarToString)"
if let match = regex.firstMatch(
in: dolarString, range:NSMakeRange(0,dolarString.utf16.count)) {
let result = (dolarString as NSString).substring(with: match.range(at:1))
myCell.label2!.text = result
}
//Label3
let zeminToString = item.Zemin
let zeminString = "\(zeminToString)"
if let match = regex.firstMatch(
in: zeminString, range:NSMakeRange(0,zeminString.utf16.count)) {
let result = (zeminString as NSString).substring(with: match.range(at:1))
myCell.label3!.text = result
}
//Label4
let renkToString = item.Renk
let renkString = "\(renkToString)"
if let match = regex.firstMatch(
in: renkString, range:NSMakeRange(0,renkString.utf16.count)) {
let result = (renkString as NSString).substring(with: match.range(at:1))
myCell.label4!.text = result
}
//Label5
let enToString = item.En
let enString = "\(enToString)"
if let match = regex.firstMatch(
in: enString, range:NSMakeRange(0,enString.utf16.count)) {
let result = (enString as NSString).substring(with: match.range(at:1))
myCell.label5!.text = result
}
//Label6
let euroToString = item.Euro
let euroString = "\(euroToString)"
if let match = regex.firstMatch(
in: euroString, range:NSMakeRange(0,euroString.utf16.count)) {
let result = (euroString as NSString).substring(with: match.range(at:1))
myCell.label6!.text = result
}
}
return myCell
}
func updateSearchResults(for searchController: UISearchController) {
if searchController.isActive {
filteredData.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (feedItems as NSArray).filtered(using: searchPredicate)
filteredData = array as! [String]
listTableView.reloadData()
}
else {
filteredData.removeAll(keepingCapacity: false)
filteredData = feedItems as! [String]
listTableView.reloadData()
}
}
}
LocationModel.Swift
import UIKit
class LocationModel: NSObject {
//properties
var DesenNo: String?
var Dolar: String?
var Zemin: String?
var En: String?
var Euro: String?
var Renk: String?
//empty constructor
override init()
{
}
//construct with #name, #address, #latitude, and #longitude parameters
init(DesenNo: String, Dolar: String, Zemin: String, En: String, Euro: String, Renk: String) {
self.DesenNo = DesenNo
self.Dolar = Dolar
self.Zemin = Zemin
self.En = En
self.Euro = Euro
self.Renk = Renk
}
//prints object's current state
override var description: String {
return "Desen: \(DesenNo), Dolar: \(Dolar), Zemin: \(Zemin), Renk: \(Renk), En: \(En), Euro: \(Euro) "
}
}
HomeModel.Swift
import UIKit
protocol HomeModelProtocol: class {
func itemsDownloaded(items: NSArray)
}
class HomeModel: NSObject {
//properties
weak var delegate: HomeModelProtocol!
let urlPath = "http://aktul.com/den.php" //this will be changed to the path where service.php lives
func downloadItems() {
let url: URL = URL(string: urlPath)!
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
let task = defaultSession.dataTask(with: url) { (data, response, error) in
if error != nil {
print("Failed to download data")
}else {
print("Data downloaded")
self.parseJSON(data!)
}
}
task.resume()
}
func parseJSON(_ data:Data) {
var jsonResult = NSArray()
do{
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
} catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let urunler = NSMutableArray()
for i in 0 ..< jsonResult.count
{
jsonElement = jsonResult[i] as! NSDictionary
let urun = LocationModel()
//the following insures none of the JsonElement values are nil through optional binding
if let desen = jsonElement["DesenNo"] as? String,
let dolar = jsonElement["Dolar"] as? String,
let zemin = jsonElement["Zemin"] as? String,
let renk = jsonElement["Renk"] as? String,
let en = jsonElement["En"] as? String,
let euro = jsonElement["Euro"] as? String
//let longitude = jsonElement["Longitude"] as? String
{
urun.DesenNo = desen
urun.Dolar = dolar
urun.Zemin = zemin
urun.Renk = renk
urun.En = en
urun.Euro = euro
}
urunler.add(urun)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.itemsDownloaded(items: urunler)
})
}
}
Update with following code in updatesearchResults function
func updateSearchResults(for searchController: UISearchController) {
if searchController.isActive {
filteredData.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = self.feedItems.filter { searchPredicate.evaluate(with: ($0 as! LocationModel).DesenNo) }
let filterArray = array.map {($0 as! LocationModel).DesenNo}
filteredData = filterArray as! [String]
tabelView.reloadData()
}
else {
filteredData.removeAll(keepingCapacity: false)
tabelView.reloadData()
}
}
I am new to Swift programming
SearchBar controller with tableview. I want display the multiple students in table view its working fine. I can add the search bar controller to table view and display the particular students data. table view cell contains the student information and image I want display particular student after search
this is the code
#IBOutlet var SearchBarDisp:UISearchBar!
override func viewDidLoad()
{
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
tableView.tableHeaderView = searchController.searchBar
}
func updateSearchResults(for searchController: UISearchController) {
//todo
}
I can get student data from json
func getKids(url : String) {
UIApplication.shared.beginIgnoringInteractionEvents()
var errorCode = "1"
var msg = "Failed"
var request = URLRequest(url: URL(string: "getstaffstudents",
relativeTo: URL(string: serverURL+"/rkapi/api/"))!)
let session = URLSession.shared
request.httpMethod = "POST"
let bodyData = "staffId=\(staffId)"
request.httpBody = bodyData.data(using: String.Encoding.utf8);
let task = session.dataTask(with:request,completionHandler:{(d,response,error)in
do{
if let data = d {
if let jsonData = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
errorCode = String(describing: jsonData["errorCode"]!)
msg = jsonData["msg"] as! String
print("msg values",msg)
if errorCode == "0" {
if let kid_list = jsonData["students"] as? NSArray {
for i in 0 ..< kid_list.count {
if let kid = kid_list[i] as? NSDictionary {
kidHoleData.removeAll()
let imageURL = url+"/images/" + String(describing: kid["photo"]!)
self.kidsData.append(Kids(
studentId: kid["studentId"] as? String,
name:kid["name"] as? String,
classId : kid["classId"] as? String,
standard: ((kid["standard"] as? String)! + " " + (kid["section"] as? String)!),
photo : (imageURL),
school: kid["schoolName"] as? String,
schoolId : "1",
url : url)
)
}
}
self.loopCount += 1
self.do_table_refresh()
}
} else {
self.displayAlert("Kids", message: msg)
}
} else {
self.displayAlert("Kids", message: "Data Not Available. Please try again")
}
}else {
self.displayAlert("Kids", message: "Please try again")
}
} catch let err as NSError {
print("JSON Error \(err)")
}
})
task.resume()
}
Table view
func numberOfSections(in tableView: UITableView) -> Int {
return (kidsData.count == 0) ? 0 : 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return kidsData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCell(
withIdentifier: "Kidscell", for: indexPath) as! KidsTableViewCell
let maskLayer = CAShapeLayer()
let bounds = cell.bounds
maskLayer.path = UIBezierPath(roundedRect: CGRect(x: 3, y: 3, width: bounds.width-15, height: bounds.height-15), cornerRadius: 2).cgPath
cell.layer.mask = maskLayer
let row = (indexPath as NSIndexPath).row
if(kidsData.count>0){
let kid = kidsData\[row\] as Kids
cell.kidNameLabel.text = kid.name
cell.classLabel.text = kid.standard
cell.kidNameLabel.lineBreakMode = .byWordWrapping
cell.kidNameLabel.numberOfLines = 0
cell.kidImageView.image = UIImage(named: "profile_pic")
cell.kidImageView.downloadImageFrom(link: kid.photo!, contentMode: UIViewContentMode.scaleAspectFit) //set your image from link array.
}
return cell
}
I want display particular student in table view(like if I can search student name as vani it's display the student vani in table view) pls help me
copy the hole data in to the attendanceInfoDupilicate
var attendanceInfoDupilicate = [AttendanceInfo]()
Inside of the Json service call at end
self.attendanceInfoDupilicate = self.attendanceInfo
updater the search controller
func updateSearchResults(for searchController: UISearchController)
{
let searchToSeatch = AttendanceSearchBarController.searchBar.text
if(searchToSeatch == "")
{
self.attendanceInfo = self.attendanceInfoDupilicate
}
else{
self.attendanceInfo.removeAll()
let AttedanceData = self.attendanceInfoDupilicate
var kidsArray = [String]()
for AttendanceInfo in AttedanceData
{
kidsArray.append(AttendanceInfo.name)
if(AttendanceInfo.name.range(of: searchToSeatch!, options: .caseInsensitive) != nil)
{
self.attendanceInfo.append(AttendanceInfo)
}
}
}
self.TableView.reloadData()
}
I am working on a project to shows news feeds to the user.
I am calling a function getNewsFeeds() to get news feeds.
I will generate new newsfeeds every one hour
ViewDidLoad(){
get current time in "HH" format and store it in currentTime
Store this currentTime in to a HoursVar variable using UserDefaults
}
ViewDidAppear(){
if( currentTime - HoursVar >= 1){
getNewsFeeds
}else{
}
retreiveStoredValuesFromUserDeafults()
}
I dont know where exactly to setup my tableViewDataSOurce and Delegate methods and reloadData to populate the tableView when getting data from the saved Userdefaults retreiveStoredValuesFromUserDeafults()
override func viewDidLoad() {
super.viewDidLoad()
hoursFormatter.dateFormat = "HH"
hoursVar = Int(hoursFormatter.string(from: hours))!
if hoursVar > 12 {
hoursVar = hoursVar - 12
}
self.defaults.set(self.hoursVar, forKey: "hoursVar")
customNavBar()
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
feedsArray = ["Reliance","Economy"]
}
override func viewDidAppear(_ animated: Bool) {
//getRssFeeds()
if((hoursVar - myHoursVar) == 1 && (hoursVar - myHoursVar) > 1){
getRssFeeds()
}else{
feedsTable.register(UITableViewCell.self, forCellReuseIdentifier: "newsFeeds")
self.feedsTable.delegate = self
self.feedsTable.dataSource = self
retreiveMyArrayData()
feedsTableView.reloadData()
}
}
func getRssFeeds(){
for i in 0..<feedsArray.count{
let url = URL(string: "https://api.cognitive.microsoft.com/bing/v5.0/news/search?q=\(feedsArray[i])&count=3&mkt=en-in")
var request = URLRequest(url: url!)
request.setValue("My Subscription Key", forHTTPHeaderField: "Ocp-Apim-Subscription-Key")
Alamofire.request(request as URLRequest).responseJSON{response in
if let json = response.result.value as? [String:AnyObject]{
if let value = json["value"]{
//
print("json \(json)")
for j in 0..<value.count{
let items = value[j] as! [String:AnyObject]
let name = items["name"] as! String
let url = items["url"] as! String
let description = items["description"] as! String
let datePublished = items["datePublished"] as! String
let dateAndTime = datePublished.replacingOccurrences(of: "T", with: " ")
self.feedsName.append(name)
self.feedsUrl.append(url)
self.feedsDescription.append(description)
self.feedsDatePublished.append(dateAndTime)
if let image = items["image"] as? [String:AnyObject]{
if let thumbnail = image["thumbnail"] as? [String:AnyObject]{
let contentUrl = thumbnail["contentUrl"] as! String
self.feedsContentUrl.append(contentUrl)
}
}else{
self.feedsContentUrl.append(self.errorImage)
}
if let provider = items["provider"]{
for i in 0..<provider.count{
let items = provider[i] as! [String:AnyObject]
let providerName = items["name"] as! String
self.feedsProvider.append(providerName)
}
}
self.feedsTable.delegate = self
self.feedsTable.dataSource = self
self.feedsTable.reloadData()
self.defaults.set(self.feedsUrl, forKey: "feedsUrl")
self.defaults.set(self.feedsDescription, forKey: "feedsDescription")
self.defaults.set(self.feedsName, forKey: "feedsName")
self.defaults.set(self.feedsProvider, forKey: "feedsProvider")
self.defaults.set(self.feedsContentUrl, forKey: "feedsContentUrl")
self.defaults.set(self.feedsDatePublished, forKey: "feedsDatePublished")
print("All Counts \(self.feedsName.count)")
}
}
}
}
}
}
func slideOpen(){
self.revealViewController().revealToggle(animated: true)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return feedsName.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "newsFeeds") as! newsFeeds
randomNumberArray = randomNumber()
//self.feedsRandomArray.append(self.feedsRandom)
print("feedsRandom \(feedsRandom)")
selectedRow = randomNumberArray[indexPath.row]
let url = URL(string: feedsContentUrl[randomNumberArray[indexPath.row]])
do{
let data = try Data(contentsOf: url!)
cell.feedsImage.image = UIImage(data: data )
}catch{
print(error)
}
let tap = UITapGestureRecognizer(target: self, action: #selector(HomeViewController.tapFunction))
let titleAttributes = [NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline), NSForegroundColorAttributeName: UIColor.purple]
let titleString = NSAttributedString(string: feedsName[randomNumberArray[indexPath.row]] , attributes: titleAttributes)
cell.feedsHeadlines.isUserInteractionEnabled = true
cell.feedsHeadlines.addGestureRecognizer(tap)
cell.feedsHeadlines.attributedText = titleString
cell.feedsDescription.text = feedsDescription[randomNumberArray[indexPath.row]]
cell.feedsPublisherName.text = feedsProvider[randomNumberArray[indexPath.row]]
cell.publishedOn.text = feedsDatePublished[randomNumberArray[indexPath.row]]
//print("All Counts \(myFeedsName.count) \(myFeedsProvider.count) \(myFeedsContentUrl.count) \(myFeedsUrl.count) \(myFeedsDescription.count) \(myFeedsDescription.count)")
return cell
}
func tapFunction(sender:UITapGestureRecognizer) {
let safariVC = SFSafariViewController(url: NSURL(string: feedsUrl[selectedRow]) as! URL)
self.present(safariVC, animated: true, completion: nil)
safariVC.delegate = self
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
func randomNumber() -> [Int] {
let feedsIndex = feedsName.count - 1
var randomNumber = Int(arc4random_uniform(UInt32(feedsIndex)))
print("Randome number \(randomNumber) \(randomNumberArray)")
for k in 0..<randomNumberArray.count{
while randomNumber == randomNumberArray[k] {
randomNumber = Int(arc4random_uniform(UInt32(feedsIndex)))
}
}
randomNumberArray.append(randomNumber)
self.defaults.set(self.randomNumberArray, forKey: "randomNumberArray")
return randomNumberArray
}
func retreiveMyArrayData(){
myFeedsUrl = defaults.stringArray(forKey: "feedsUrl") ?? [String]()
myFeedsDescription = defaults.stringArray(forKey: "feedsDescription") ?? [String]()
myFeedsName = defaults.stringArray(forKey: "feedsName") ?? [String]()
myFeedsProvider = defaults.stringArray(forKey: "feedsProvider") ?? [String]()
myFeedsContentUrl = defaults.stringArray(forKey: "feedsContentUrl") ?? [String]()
myFeedsDatePublished = defaults.stringArray(forKey: "feedsDatePublished") ?? [String]()
myHoursVar = defaults.integer(forKey: "hoursVar")
myFeedsRandom = defaults.array(forKey: "randomNumberArray") as! [Int]
print("Values \(myHoursVar) \(myFeedsProvider) \(myFeedsUrl.count)")
}
You can set UITableViewDataSourceand UITableViewDelegate into .xib
//Setting datasource & delegate for tableview inside viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
self.feedsTableView.delegate = self
self.feedsTableView.datasource = self
}
Now, you need to reload the tableview when you setValue & retrieve the value to the userDefaults. self.feedsTableView.reloadData()
If this didn't helped you, please let me know. I'll work more to provide you with a complete workflow for the above project.
I'm working with a collectionView right now and when I activate the refresh control, it adds a duplicate picture to the data source set for every picture in the set, and then makes it disappear and things go back to normal by the time the refresh control is done. Here's a YouTube video I uploaded to clearly show you what is going on.
https://youtu.be/Q9ZFd-7tSRw
It would seem logical that the data source set would be getting the same data from the API I am using, then displaying it, the duplicate data then getting deleting from the array, and then the collection view being reloaded once more before the refresh control goes away. That's not how I want it to work obviously, but perhaps I have coded it wrong.
viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView!.registerClass(PhotoBrowserCollectionViewCell.self, forCellWithReuseIdentifier: PhotoBrowserCellIdentifier)
self.cellLoadingIndicator.backgroundColor = goldenWordsYellow
self.cellLoadingIndicator.hidesWhenStopped = true
if self.revealViewController() != nil {
revealViewControllerIndicator = 1
menuButton.target = self.revealViewController()
menuButton.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
self.revealViewController().rearViewRevealWidth = 280
collectionView!.delegate = self
collectionView!.dataSource = self
goldenWordsRefreshControl = UIRefreshControl()
goldenWordsRefreshControl.backgroundColor = goldenWordsYellow
goldenWordsRefreshControl.tintColor = UIColor.whiteColor()
self.collectionView!.addSubview(goldenWordsRefreshControl)
navigationController?.setNavigationBarHidden(false, animated: true)
navigationItem.title = "Pictures"
setupView()
populatePhotos()
self.dateFormatter.dateFormat = "dd/MM/yy"
self.cellLoadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
self.cellLoadingIndicator.color = goldenWordsYellow
self.cellLoadingIndicator.center = (self.collectionView?.center)!
self.collectionView!.addSubview(cellLoadingIndicator)
self.collectionView!.bringSubviewToFront(cellLoadingIndicator)
/*
self.dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
self.dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
let currentDateAndTime = NSDate()
let updateString = "Last updated at " + self.dateFormatter.stringFromDate(currentDateAndTime)
self.goldenWordsRefreshControl.attributedTitle = NSAttributedString(string: updateString)
*/
}
populatePhotos:
func populatePhotos() {
if populatingPhotos {
return
}
populatingPhotos = true
self.cellLoadingIndicator.startAnimating()
self.temporaryPictureObjects.removeAllObjects()
Alamofire.request(GWNetworking.Router.Pictures(self.currentPage)).responseJSON() { response in
if let JSON = response.result.value {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)) {
var nodeIDArray : [Int]
if (JSON .isKindOfClass(NSDictionary)) {
for node in JSON as! Dictionary<String, AnyObject> {
let nodeIDValue = node.0
var lastItem : Int = 0
self.nodeIDArray.addObject(nodeIDValue)
if let pictureElement : PictureElement = PictureElement(title: "Picture", nodeID: 0, timeStamp: 0, imageURL: "http://goldenwords.ca/sites/all/themes/custom/gw/logo.png", author: "Staff", issueNumber: "Issue # error", volumeNumber: "Volume # error") {
pictureElement.title = node.1["title"] as! String
pictureElement.nodeID = Int(nodeIDValue)!
let timeStampString = node.1["revision_timestamp"] as! String
pictureElement.timeStamp = Int(timeStampString)!
if let imageURL = node.1["image_url"] as? String {
pictureElement.imageURL = imageURL
}
if let author = node.1["author"] as? String {
pictureElement.author = author
}
if let issueNumber = node.1["issue_int"] as? String {
pictureElement.issueNumber = issueNumber
}
if let volumeNumber = node.1["volume_int"] as? String {
pictureElement.volumeNumber = volumeNumber
}
lastItem = self.temporaryPictureObjects.count // Using a temporary set to not handle the dataSource set directly (safer).
self.temporaryPictureObjects.addObject(pictureElement)
let indexPaths = (lastItem..<self.temporaryPictureObjects.count).map { NSIndexPath(forItem: $0, inSection: 0) }
}
}
/* Sorting the elements in order of newest to oldest (as the array index increases] */
let timeStampSortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
self.pictureObjects.sortUsingDescriptors([timeStampSortDescriptor])
}
dispatch_async(dispatch_get_main_queue()) {
self.pictureObjects = self.temporaryPictureObjects
self.collectionView!.reloadData()
self.cellLoadingIndicator.stopAnimating()
self.currentPage++
self.populatingPhotos = false
}
}
}
}
}
handleRefresh:
func handleRefresh() {
goldenWordsRefreshControl.beginRefreshing()
self.pictureObjects.removeAllObjects()
self.currentPage = 0
self.cellLoadingIndicator.startAnimating()
self.picturesCollectionView.bringSubviewToFront(cellLoadingIndicator)
self.populatingPhotos = false
populatePhotos()
self.cellLoadingIndicator.stopAnimating()
goldenWordsRefreshControl.endRefreshing()
}
cellForItemAtIndexPath:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(PhotoBrowserCellIdentifier, forIndexPath: indexPath) as! PhotoBrowserCollectionViewCell
if let pictureObject = pictureObjects.objectAtIndex(indexPath.row) as? PictureElement {
let title = pictureObject.title ?? "" // if pictureObject.title == nil, then we return an empty string
let timeStampDateObject = NSDate(timeIntervalSince1970: NSTimeInterval(pictureObject.timeStamp))
let timeStampDateString = dateFormatter.stringFromDate(timeStampDateObject)
let author = pictureObject.author ?? ""
let issueNumber = pictureObject.issueNumber ?? ""
let volumeNumber = pictureObject.volumeNumber ?? ""
let nodeID = pictureObject.nodeID ?? 0
let imageURL = pictureObject.imageURL ?? "http://goldenwords.ca/sites/all/themes/custom/gw/logo.png"
cell.request?.cancel()
if let image = self.imageCache.objectForKey(imageURL) as? UIImage {
cell.imageView.image = image
} else {
cell.imageView.image = nil
cell.request = Alamofire.request(.GET, imageURL).responseImage() { response in
if let image = response.result.value {
self.imageCache.setObject(response.result.value!, forKey: imageURL)
if cell.imageView.image == nil {
cell.imageView.image = image
}
}
}
}
}
return cell
}