import UIKit
import RealmSwift
class ViewController: UIViewController , UITableViewDataSource , UITableViewDelegate {
#IBOutlet weak var text1: UITextField!
#IBOutlet weak var text2: UITextField!
#IBOutlet weak var ttableview: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array1.count
}
func ttableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array1.count
}
/////
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = ttableview.dequeueReusableCell(withIdentifier: "cell") as! Cell
cell.lable1.text = array1[indexPath.row]
cell.lable2.text = array2[indexPath.row]
return cell
}
/////
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
//this delet Realm
let cat1 = array1[indexPath.row]
let cat2 = array2[indexPath.row]
let realm = try! Realm()
try realm.write {
realm.delete(cat1)
realm.delete(cat2)
}
//this delete table view row and array
array1.remove(at: indexPath.row)
array2.remove(at: indexPath.row)
ttableview.deleteRows(at: [indexPath], with: .fade)
}
}
var array1 = [String]()
var array2 = [String]()
///////////////////
//add 2 text filed in tableview
#IBAction func Add(_ sender: Any) {
addCat()
array1.insert(text1.text!, at: 0)
array2.insert(text2.text!, at: 0)
self.ttableview.reloadData()
}
/////////////
func addCat(){
let realm = try! Realm()
let mike = CCat()
mike.name = (text1.text!)
mike.job = (text2.text!)
try! realm.write {
realm.add(mike)
//print(" \(mike.name) and \(mike.job)")
}
}
////////////////
func queryPeople(){
let realm = try! Realm()
let allPeople = realm.objects(CCat.self)
// var byname = allPeople.sorted(byProperty: "name", ascending: false)
for person in allPeople {
array1.insert(person.name, at: 0)
array2.insert(person.job, at: 0)
print("\(person.name) to \(person.job)")
ttableview.reloadData()
}
}
///////////////////
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
ttableview.delegate = self
ttableview.dataSource = self
// addCat()
queryPeople()
}
The objects you store in Realm are from CCat class (which hopefully inherits from Object), hence you can write (add) them to Realm database.
But as the Xcode says, you are trying to delete a String from realm. Which is not possible.
Related
Here I have a Realm Database which is have some data in it and I want to display it on my Stimulator but it turn out display some other thing. What's wrong in my code?
This is the data of my Realm Database and I also marked the data which I want to display it.
The stimulator which display something like this.
And here is my ViewController.swift code's.
import UIKit
import RealmSwift
class ViewController: UIViewController,UITableViewDataSource { //UITableViewDataSource
#IBOutlet weak var mytableview: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let realm = try! Realm()
let theItem = realm.objects(Item.self).filter("itemid >= 1")
return theItem.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let realm = try! Realm()
let theItem = realm.objects(Item.self).filter("itemid >= 1")
print(theItem)
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1")
//I suspect the problem is at here...
cell?.textLabel?.text = "\(theItem)"
return cell!
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
class Category: Object {
#objc dynamic var name: String?
#objc dynamic var caid: Int = 0
}
class Item: Object {
#objc dynamic var name: String?
#objc dynamic var itemid: Int = 0
#objc dynamic var cateid: Int = 0
}
Your problem is that you need to get the string from the Item object. try something like
"\(theItem.name)".
func getNames() -> [String]{
let items = realm.objects(Item.self).filter("itemid >= 1").toArray(ofType: Item.self ) as [Item]
return items.map { $0.name }
}
extension Results {
func toArray<T>(ofType: T.Type) -> [T] {
var array = [T]()
for i in 0 ..< count {
if let result = self[i] as? T {
array.append(result)
}
}
return array
}
}
I found a way to display the data already. I just need to add indexPath.row in my code and it can handle the data already.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let realm = try! Realm()
let theItem = realm.objects(Item.self).filter("itemid >= 1")
//I only add below this indexpath
let cellData = theItem[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1")
//and change this part and it's done.
cell?.textLabel?.text = cellData.name
print(theItem)
return cell!
}
Im having issues saving the table view data to user defaults, im getting the error " Cannot assign value of type '[String]' to type '[ViewController.ItemRow]' " in the load function. It gives the error at the line "items = loadedData". Does anyone know why its giving me this error!I dont know if im even doing it right.
import UIKit
import SafariServices
class ViewController: UIViewController, UIAdaptivePresentationControllerDelegate, UITextFieldDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var OrderNumberLabel: RoundedLabel2!
#IBOutlet weak var CostLabel: RoundedLabel2!
#IBOutlet weak var ProfitLabel: RoundedLabel2!
#IBOutlet weak var TotalLabel: RoundedLabel2!
#IBOutlet weak var itemTextField: UITextField!
#IBOutlet weak var priceTextField: UITextField!
#IBOutlet weak var saleTextField: UITextField!
var items: [ItemRow] = []
struct ItemRow
{
var first: String
var second: String
var third: String
}
override func viewDidLoad() {
super.viewDidLoad()
load()
// tableView.tableFooterView = UIView(frame: CGRect.zero)
}
func save(){
UserDefaults.standard.set(items, forKey: "saved")
}
func load(){
if let loadedData:[String] = UserDefaults.standard.value(forKey: "saved") as? [String]{
items = loadedData
tableView.reloadData()
}
}
#IBAction func addButtonTapped(_ sender: Any) {
insertNewItems()
save()
// profit()
//
}
// func profit(){
// let priceValue = Double(priceTextField.text!)
// let saleValue = Double(saleTextField.text!)
//
// if priceValue != nil && saleValue != nil {
//
// let outputValue = Double (priceValue! - saleValue!)
//
// ProfitLabel.text = "\(outputValue)"
// }
// }
func insertNewItems() {
let newVideoRow = ItemRow(first: itemTextField.text!, second: priceTextField.text!, third: saleTextField.text!)
items.append(newVideoRow)
let indexPath = IndexPath(row: items.count - 1, section: 0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
itemTextField.text = ""
priceTextField.text = ""
saleTextField.text = ""
view.endEditing(true)
}
}
extension ViewController: UITableViewDelegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let ItemTitle = items[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell") as! ItemCell
cell.itemLabel.text = ItemTitle.first
cell.priceLabel.text = ItemTitle.second
cell.saleLabel.text = ItemTitle.third
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
items.remove(at: indexPath.row)
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
save()
}
}
}
Make your struct conform to the Codable protocol. This is as simple as changing one line to:-
struct ItemRow : Codable
Your save function can be:-
if let data = try? PropertyListEncoder().encode(items) {
UserDefaults.standard.set(data, forKey: "SavedItems")
}
And load can be:
let defaults = UserDefaults.standard
if let data = defaults.data(forKey: "SavedItems") {
items = try! PropertyListDecoder().decode([ItemRow].self, from: data)
tableView.reloadData()
}
A quick look around SO the opinion seems to be that this shouldn't be used for large data sets. So this will get you started, but it may be worth considering a solution a bit more 'database-y' if you need larger amounts of data (e.g. CoreData or Realm).
My app is not correctly displaying all of the items in my array. What is causing this to happen?
var songamount = ["Refresh Page"]
var songImageAmount = [MPMediaItemArtwork]()
override func viewDidLoad() {
super.viewDidLoad()
MPMediaLibrary.requestAuthorization { (status) in
let myPlaylistQuery = MPMediaQuery.playlists()
let playlists = myPlaylistQuery.collections
self.songamount.remove(at: 0)
for playlist in playlists! {
print(playlist.value(forProperty: MPMediaPlaylistPropertyName)!)
let songs = playlist.items
for song in songs {
let songTitle = song.value(forProperty: MPMediaItemPropertyTitle)
let songImage = song.artwork
self.songamount.append(songTitle as! String)
self.songImageAmount.append(songImage!)
print("\t\t", songTitle!)
}
print(self.songamount)
print("Song Amount:\(self.songamount.count)")
print("Image Amount: \(self.songImageAmount.count)")
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return songamount.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "LibraryCell", for: indexPath) as! LibraryCell
cell.LibraryTitle.text = songamount[indexPath.row]
//cell.LibraryImage.image = songImageAmount[indexPath.row]
print(indexPath)
return cell
}
}
This is my code to show all the songs in a users Itunes library but it is only displaying 20 items from the array in the tableView.
Update- I have got it to correctly make a list of all my songs but it is only showing 33 of them in the list. Here is the updated code
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var TextDebug: UILabel!
var songamount = ["Please Reload View"]
var songImageAmount = [MPMediaItemArtwork]()
override func viewDidLoad() {
super.viewDidLoad()
MPMediaLibrary.requestAuthorization { (status) in
let mySongQuery = MPMediaQuery.songs()
let songs = mySongQuery.collections
self.songamount.remove(at: 0)
for song in songs! {
print(MPMediaItemPropertyTitle)
let songs = song.items
for song in songs {
let songTitle = song.value(forProperty: MPMediaItemPropertyTitle)
//let songImage = song.artwork
self.songamount.append(songTitle as! String)
//self.songImageAmount.append(songImage!)
print("\t\t", songTitle!)
}
print(self.songamount)
print("Song Amount:\(self.songamount.count)")
//print("Image Amount: \(self.songImageAmount.count)")
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return songamount.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "LibraryCell", for: indexPath) as! LibraryCell
cell.LibraryTitle.text = songamount[indexPath.row]
//cell.LibraryImage.image = songImageAmount[indexPath.row]
let sections: Int = tableView.numberOfSections
var rows: Int = 0
for i in 0..<sections {
rows += tableView.numberOfRows(inSection: i)
TextDebug.text = "\(rows)"
}
return cell
}
The solution to my problem was to add tableView.reloadData() to the end of viewDidLoad()
I have a program written in Swift 3, that grabs JSON from a REST api and appends it to a table view.
Right now, I'm having troubles with getting it to print in my Tableview, but it does however understand my count function.
So, I guess my data is here, but it just doesn't return them correctly:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, HomeModelProtocal {
#IBOutlet weak var listTableView: UITableView!
func itemsDownloaded(items: NSArray) {
feedItems = items
self.listTableView.reloadData()
}
var feedItems: NSArray = NSArray()
var selectedLocation : Parsexml = Parsexml()
override func viewDidLoad() {
super.viewDidLoad()
self.listTableView.delegate = self
self.listTableView.dataSource = self
let homeModel = HomeModel()
homeModel.delegate = self
homeModel.downloadItems()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier: String = "BasicCell"
let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
let item: Parsexml = feedItems[indexPath.row] as! Parsexml
myCell.textLabel!.text = item.title
return myCell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return feedItems.count
}
override func viewDidAppear(_ animated: Bool) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Are you by any chance able to see the error that I can't see?
Note. I have not added any textlabel to the tablerow, but I guess that there shouldn't be added one, when its custom?
Try this code:
override func viewDidLoad() {
super.viewDidLoad()
print(yourArrayName.count) // in your case it should be like this print(feedItems.count)
}
My Code:
import UIKit
class HomeVCHome: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var usernameLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
var names: [String] = []
var contacts: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self;
self.tableView.dataSource = self;
let url=NSURL(string:"http://mysite/json.aspx")!
let allContactsData=NSData(contentsOfURL:url)
var allContacts: AnyObject! = NSJSONSerialization.JSONObjectWithData(allContactsData!, options: NSJSONReadingOptions(0), error: nil)
if let json = allContacts as? Array<AnyObject> {
print(json)
for index in 0...json.count-1 {
let contact : AnyObject? = json[index]
print(contact)
let collection = contact! as Dictionary<String, AnyObject>
print(collection)
print(collection["name"])
let name : AnyObject? = collection["name"]
let cont : AnyObject? = collection["cont"]
names.append(name as String)
contacts.append(cont as String)
}
}
println(names)
println(contacts)
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.names.count;
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected name : "+names[indexPath.row])
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell = tableView.dequeueReusableCellWithIdentifier("cell") as? UITableViewCell
println("ok 1")
if !(cell != nil) {
cell = UITableViewCell(style: .Subtitle, reuseIdentifier: "cell")
}
println("ok 2")
cell?.textLabel.text=self.names[indexPath.row]
cell?.detailTextLabel?.text = self.contacts[indexPath.row]
println("ok 3")
return cell!
}
}
i try to run, and i can't see my data in tableView... just blank in table View
and i try another code but the same result (table view blank)...
what should i do? i don't know its my mistake code or my simulator have problems like that...
pls change the method and try:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier(simpleTableIdentifier) as UITableViewCell
cell.textLabel.text=self.names[indexPath.row]
cell.detailTextLabel?.text = self.contacts[indexPath.row]
return cell
}