Set up WatchKit Table - ios

I'm trying to load my data into a WatchKit table. Basically, set the text of the match label in each table group cell with the array of matchs I have.
I've got the data, and everything set up, but actually loading it into the table is where I'm stuck.
InterfaceController.swift:
var receivedData = Array<Dictionary<String, String>>()
var eventsListSO = Array<Event>()
#IBOutlet var rowTable: WKInterfaceTable!
func doTable() {
eventsListSO = Event.eventsListFromValues(receivedData)
rowTable.setNumberOfRows(eventsListSO.count, withRowType: "rows")
for var i = 0; i < self.rowTable.numberOfRows; i++ {
let row = rowTable.rowControllerAtIndex(i) as? TableRowController
for eventm in eventsListSO {
row!.mLabel.setText(eventm.eventMatch)
NSLog("SetupTableM: %#", eventm.eventMatch)
}
}
}
I was trying to do it in doTable because that seemed like best place to do this, and I think doTable is set up right, but I'm not sure? Not sure if I need to make the array an optional type or what.
Here is the referencing code if needed:
RowController.swift:
class TableRowController {
#IBOutlet var mLabel: WKInterfaceLabel!
#IBOutlet var cGroup: WKInterfaceGroup!
}
Event.swift:
class Event {
var eventTColor:String
var eventMatch:String
init(dataDictionary:Dictionary<String,String>) {
eventTColor = dataDictionary["TColor"]!
eventMatch = dataDictionary["Match"]!
}
class func newEvent(dataDictionary:Dictionary<String,String>) -> Event {
return Event(dataDictionary: dataDictionary)
}
class func eventsListFromValues(values: Array<Dictionary<String, String>>) -> Array<Event> {
var array = Array<Event>()
for eventValues in values {
let event = Event(dataDictionary: eventValues)
array.append(event)
}
return array
}
}
So I'm not sure if:
- doTable is set up right (can't be because eventsListSO.count is null)

The way you work with tables in WatchKit is a lot different than UIKit.
After you call setNumberOfRows you need to iterate over each row and get the RowController.
for var i = 0; i < self.rowTable.numberOfRows; i++ {
var row = self.rowTable.rowControllerAtIndex(i)
//setup row here
}

You can check Raywenderlich's tutorial about WatchKit: http://www.raywenderlich.com/96741/watchkit-tutorial-with-swift-tables-glances-and-handoff, it teach you how to show tables on your watch, hope this help!

Related

How can I use one view controller with different Realm classes

I am trying to create an app where I have 4 buttons which each one corresponds to a different category. Now the categories are different Realm Objects saved in a swift file.
class HealthData: Object {
#objc dynamic var name : String = ""
}
class SelfImprovement: Object {
#objc dynamic var name : String = ""
}
class TopSecret: Object {
#objc dynamic var name : String = ""
}
class Ohter: Object {
#objc dynamic var name : String = ""
}
Now my problem is that I want a single view controller with a TableView to have different data that will get passed on to TableView from the corresponding category.
My idea was that I can create the var categories : Results<HealthData>! and use an if statement to change the categories to be Results etc using the prepare for a segue to know which button was pressed.
override func viewWillAppear(_ animated: Bool) {
if categoryNo == 1 {
title = "Health"
} else if categoryNo == 2 {
title = "Self Improvement"
categories = Results<SelfImprovement>!
}
}
But of course, XCode cannot assign the value of type 'Results?.Type' to type 'Results?'.
Any ideas?
Thank you all for your time!
So the issue is you want to re-use the tableView to display data from different tableView datasources. You're heading down the right path but the answer is to tell the tableView where to get it's data from.
I am pairing this down to really basic code so don't copy paste - trying to keep it short.
Assume we have a view controller with a tableView
class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
#IBOutlet weak var myTableView: NSTableView!
var myHealthArray = [String]() //one tableview datasource
var mySelfImprovementArray = [String]() //another tableview datasource
var tableType = "" //will tell the tableView what it should be displaying
then, further down, we have the tableView delegate methods that populate the tableview
func numberOfRows(in tableView: NSTableView) -> Int {
if self.tableType == "health" {
return self.myHealthArray.count
} else if self.tableType == "self_improvement" {
return self.mySelfImprovementArray.count
} //etc
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let cell = tableView.makeView(withIdentifier: myIdentifier, owner: self) as! NSTableCellView
var s = ""
if self.tableType == "health" {
s = self.myHealthArray[row]
} else if self.tableType == "self_improvement" {
s = self.mySelfImprovementArray[row]
} //etc
cell.textField?.stringValue = s
return cell
}
So the idea here is to set the tableType to whatever is supposed to be displayed in the tableView then the logic within the tableView delegate methods will know which dataSource array to get its data from.
It's important to remember that Realm Results are homogenous so they can only store one type of object.
In this example, I defined the dataSources as strings but in your case they may be realm results objects. If they are strings, you could just re-use the array as it would only contain string objects. However, if the dataSources are Realm Results, you'll need separate arrays as shown in this answer.

How to get the unique id's of objects in an array swift

I have a custom class like this -
class Event: NSObject
{
var eventID: String?
var name:String?
}
Now i have an array of Event object's like
var events = [Event]()
var event1 = Event()
event1.eventID = "1"
event1.name = "Anu"
var event2 = Event()
event2.eventID = "2"
event2.name = "dev"
var event3 = Event()
event3.eventID = "1"
event3.name = "Anu"
events.append(event1)
events.append(event2)
events.append(event3)
to get the unque eventID's from array i have written code like this which is working great -
func getUniqueIDsFromArrayOfObjects(events:[Event])->NSArray
{
let arr = events.map { $0.eventID!}
let uniquearr:NSMutableArray = NSMutableArray()
for obj in arr
{
if !uniquearr.containsObject(obj) {
uniquearr.addObject(obj)
}
}
return uniquearr;
}
print(getUniqueIDsFromArrayOfObjects(events))
I wanted to know is there any alternate way to get the unique id's from array of objects more effectively than i am using . May be something by using NSPredicate.
Because an array having thousands of objects, my code going to do more iteration .
You can use a Set to obtain only the unique values. I would suggest that you have your function return a Swift array rather than NSArray too.
func getUniqueIDsFromArrayOfObjects(events:[Event])->[String]
{
let eventIds = events.map { $0.eventID!}
let idset = Set(eventIds)
return Array(idset)
}
let uniqueRecords = jobs.reduce([], {
$0.contains($1) ? $0 : $0 + [$1]
})
A Set is a collection similar to an array, which prevents duplicates. You can do:
func getUniqueIDsFromArrayOfObjects(events:[Event])->[Event] {
return Array(Set(events.map { $0.eventID! }))
}
Note that the order of the items in a set is undefined, so if you care about the order of the elements, you should try a different solution.

Swift - Find duplicates Elements in a List

i have the following list of UITextField:
let list = [(name1TextField, phone1TextField), (name2TextField, phone2TextField), (name3TextField, phone3TextField), (name4TextField, phone4TextField), (name5TextField, phone5TextField)]
i'm trying to find phones duplicates and print them out
EDIT
e.g. (tuples could be empty)
list = [("john", "555-444-333"), ("james", "555-444-333"), ("",""), ("bob", "333-222-111"), ("nancy", "222-111-444"), ]
output 555-444-333
how can i do?
Given this
var name1TextField: UITextField!
var phone1TextField: UITextField!
var name2TextField: UITextField!
var phone2TextField: UITextField!
var name3TextField: UITextField!
var phone3TextField: UITextField!
var name4TextField: UITextField!
var phone4TextField: UITextField!
var name5TextField: UITextField!
var phone5TextField: UITextField!
And this
let list = [(name1TextField, phone1TextField), (name2TextField, phone2TextField), (name3TextField, phone3TextField), (name4TextField, phone4TextField), (name5TextField, phone5TextField)]
Solution
let repeatedPhones = list
.flatMap { $0.1?.text }
.reduce([String:Int]()) { (var dict, phone) -> [String:Int] in
dict[phone] = (dict[phone] ?? 0) + 1
return dict
}
.filter { $0.1 > 1 && !$0.0.isEmpty }
.map { $0.0 }
Using dictionary to record how many time you see a phone number:
var dict = [String: Int]()
And then go thru the whole list:
for (_, phone) in list {
if let count = dict[phone] {
dict[phone] = count + 1
} else {
dict[phone] = 1
}
}
After this you will have a dictionary which contains the phone number and the count of each phone number appear in the list
for item in dict {
if item.1 > 1 {
print(item.0)
}
}
This method has a time complexity: O(2n)
And this question looks like a duplicate of Find Duplicate Elements In Array Using Swift
You can create a list of the last tuple items and then, as you add them to a new array, check if they are already contained in the array.
So something like:
func processList(list) -> String {
var bufferArray[String] = []
for (int i = 0; i < list.size; i++) {
if !(bufferArray.contains( list[i].1 )) {
bufferArray.add(list[i].1)
else {
return list[i].1
}
}
}
What I would do is the following:
var duplicates = []
var set = Set<String>()
for tuple in list {
if set.contains(tuple.phoneTextField.text) {
duplicates.append(tuple.phoneTextField.text)
} else {
set.insert(tuple.phoneTextField.text)
}
}
At the end you would do whatever you want with the duplicates array.

Vote implementation in parse

I am stuck for a very long time. I am trying to implement a vote feature in a collection view. If the user taps the button it adds one vote to parse and shows it on the label. My code does that however when I look into the parse dashboard I see that a new row is create and the number of votes is not going into the post
My code for the cell is
import UIKit
import ParseUI
import Parse
var votes = [PFObject]()
class NewCollectionViewCell: UICollectionViewCell {
var parseObject = PFObject(className: "Posts")
#IBOutlet weak var postsImageView: PFImageView!
#IBOutlet weak var postsLabel: UILabel!
#IBOutlet weak var votesLabel:UILabel?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
postsLabel.textAlignment = NSTextAlignment.Center
print("Passing11")
}
#IBAction func vote(sender: AnyObject) {
if let votes = parseObject.objectForKey("votes") as? Int {
parseObject.setObject(votes + 1, forKey: "votes")
parseObject.saveInBackgroundWithTarget(nil, selector: nil)
votesLabel?.text = "\(votes + 1) votes"
print("Passing22")
}
else
{
parseObject.setObject(1, forKey: "votes")
parseObject.saveInBackgroundWithTarget(nil, selector: nil)
votesLabel?.text = "1 votes"
print("Passing33")
}
}}
and collection view is
if let votes = parseObject.objectForKey("votes") as? Int {
cell.votesLabel?.text = "\(votes) votes"
}
else
{
cell.votesLabel?.text = "0 votes"
}
return cell
}
How can I make it work? Thank you.
From what I remember in my Parse project. If you need to retrieve and update an existing row in Parse you need to create a PFQuery object first and retrieve the desired row using that query object. And then you can update its "vote" or whatever attribute value you want to. Kindly try that.

Array appending not working across files in swift

Im currently implementing a like functionality in my app, and I can't seem to be able to get this append and retrieving to work. Here is my Button Action which is found in my ViewController file
var Liked = Favourite()
let factBook = FactBook()
#IBAction func favour() {
var currentQuote = factBook.factsArray[factIndex]
Liked.favouriteArray.append(currentQuote)
}
The Favourite struct is called from
import Foundation
struct Favourite {
var favouriteArray: [String] = []
}
(The factBook struct is the same thing except the array actually has elements inside.)
Now my goal is to get all this to display on a separate view controller called favouriteViewController:
import UIKit
class FavouriteViewController: UIViewController {
#IBOutlet var LikeQuote: UILabel!
var liked = Favourite()
override func viewDidLoad() {
super.viewDidLoad()
if liked.favouriteArray.count > 0 {
LikeQuote.text = liked.favouriteArray[0]
} else if liked.favouriteArray.count == 0 {
LikeQuote.text = "No Liked Quotes Found, Go Favour Some!"
}
}
Now when I hit the button, theoretically I should be able to append it to the favouriteArray and then be able to display it on my favouriteViewController file, however when I save it and then open viewcontroller file it defaults to the liked.favouriteArray.count=0 scenario and prints out the text no matter how many quotes I save. I just need an idea of what's going wrong in this process?
Update: If I put append Hello world into text it still does not append to element and evaluates the array value as 0.
The problem is that because you are not saving the data somewhere like into a database or file, you won't be able to retrieve it so the code you add into the viewDidLoad will not work The only way for it to work is when the UIButton was tapped check the code below. Hope that Helps
import Foundation
import UIKit
struct Favourite {
var favouriteArray = [String]()
}
class FavouriteViewController: UIViewController {
// let factBook = FactBook()
#IBOutlet var LikeQuote: UILabel!
var liked = Favourite()
override func viewDidLoad() {
super.viewDidLoad()
}
func updateContent(){
if liked.favouriteArray.count > 0 {
LikeQuote.text = liked.favouriteArray[0]
}
else if liked.favouriteArray.count == 0 {
LikeQuote.text = "No Liked Quotes Found, Go Favour Some!"
}
}
#IBAction func favour() {
// var currentQuote = liked.factsArray[factIndex]
// Liked.favouriteArray.append(currentQuote)
liked.favouriteArray.append("today is a new day ")
updateContent()
}
}

Resources