I'm trying to find a "cleaner-elegant" way to pass data between UIViewControllers. So, I decided to proceed using Delegates and Protocols. However, I failed on receive the data provided by my Protocol. What am I doing wrong?
Trying to receive the protocol data and use it to populate a UITableView:
class ViewController: UIViewController, CLLocationManagerDelegate, UITableViewDataSource, dataReceivedDelegate {
func dataReceived(nome: String, foto: UIImage, qtd: Int) {
nomeReceived = nome
self.qtd = qtd
self.itensTableView.reloadData()
}
#IBOutlet weak var itensTableView: UITableView!
var arrayNomes = NSMutableArray()
var nomeReceived = ""
var qtd:Int = 0
var objetos = [Objeto]()
//TableView
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let item = objetos[indexPath.row]
let cell = itensTableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! tableviewCell
cell.nameCell.text = nomeReceived //Nil value
// cell.imageViewCell.image = item.foto //Nil value
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return qtd
}
override func viewDidAppear(_ animated: Bool) {
let controller = storyboard?.instantiateViewController(withIdentifier: "addVc") as! adicionarNovoItemVc
controller.delegate = self
}
Creating and setting value to the Protocol:
import UIKit
protocol dataReceivedDelegate {
func dataReceived(nome:String,foto:UIImage,qtd:Int)
}
class adicionarNovoItemVc: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITextFieldDelegate {
#IBOutlet weak var textFieldNome: UITextField!
let imagePicker = UIImagePickerController()
#IBOutlet weak var namePreview: UILabel!
#IBOutlet weak var imagePreview: UIImageView!
let picker = UIImagePickerController()
var delegate:dataReceivedDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.textFieldNome.delegate = self
// Do any additional setup after loading the view.
}
#IBAction func botaoAdcItem(_ sender: UIButton) {
if (self.namePreview!.text != nil) && (self.imagePreview!.image != nil) {
delegate?.dataReceived(nome: self.namePreview.text!, foto: self.imagePreview.image!, qtd: 1)
self.navigationController?.popViewController(animated: true)
}
else {return}
}
In your ViewController add an action to button,
func buttonAction(sender: UIButton!) {
let storyboard = UIStoryboard.init(name: "yourStoryboarName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "addVc") as! adicionarNovoItemVc
controller.delegate = self
self.navigationController?.pushViewController(controller, animated: true)
}
Once new controller is pushed on screen, you can execute 'botaoAdcItem' action and rest will get you expected result.
Related
I have two view controllers, one with a table view (first VC) and a second one that can be navigated to via a button in the navigation bar. The second view controller is supposed to be able to add a table view cell into the tableview of the first view controller.
First View Controller:
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView = UITableView()
var data = ["mars", "earth", "jupiter", "venus", "saturn"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.addSubview(tableView)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.delegate = self
tableView.dataSource = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.frame = view.bounds
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = data[indexPath.row]
return cell
}
Second View Controller:
import UIKit
class SecondViewController: UIViewController {
#IBOutlet var imageView: UIImageView!
#IBOutlet var button: UIButton!
#IBOutlet var addPostButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
title = "Second Screen"
// Do any additional setup after loading the view.
}
#IBAction func didTapButton(){
let picker = UIImagePickerController()
picker.sourceType = .photoLibrary
picker.allowsEditing = true
picker.delegate = self
present(picker, animated: true)
}
#IBAction func didTapAddPostButton(){
let FVC = FirstViewController()
FVC.data.append("New data added!")
DispatchQueue.main.async{
FVC.tableView.beginUpdates()
FVC.tableView.performBatchUpdates({
FVC.tableView.insertRows(at: [IndexPath(row: FVC.data.count - 1,
section: 0)],
with: .automatic)
}, completion: nil)
FVC.tableView.endUpdates()
}
print("TapAddPostButton pressed")
print(FVC.data)
}
}
extension SecondViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true, completion: nil)
guard let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage else {
return
}
imageView.image = image
}
}
What's supposed to happen: upon pressed the button in the second view controller, a new table cell is supposed to be added and then the tableview reloaded.
What's actually happening: the tableview is not being reloaded. When i swipe back to the first view controller, the tableview is the same as before and has not reloaded and updated with the new cell.
Images:
This is the first view controller
This is the second view controller
When you do:
let FVC = FirstViewController()
... you're creating a new, unrelated instance of FirstViewController. This won't work. Look into delegates + protocols or closures (or show code for where you are presenting SecondViewController and I'll update my answer).
If you need to achieve it, it's better to use protocols to be able to link these two viewControllers in the correct way.
Creating a protocol In anywhere you need:
protocol PassingProtocol {
func saveData(withText myText: String)
}
then in FirstViewController:
extension FirstViewController: PassingProtocol {
func saveData(withText myText: String) {
data.append(myText)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
In the Action of NewEntry Barbutton :
let myVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as! SecondViewController
myVC.textDelegate = self
self.navigationController?.pushViewController(myVC, animated: true)
}
In the SecondViewController:
var textDelegate: PassingProtocol!
Then in the action of didTapAddPostButton :
textDelegate.saveData(withText: "New data added!")
If you need to use outlets follow the below steps:
FirstViewController.Swift:
import UIKit
class FirstViewController: UIViewController {
var data = ["mars", "earth", "jupiter", "venus", "saturn"]
#IBOutlet weak var tableViewOutlet: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func newEntryAction(_ sender: Any) {
let myVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as! SecondViewController
myVC.textDelegate = self
self.navigationController?.pushViewController(myVC, animated: true)
}
}
extension FirstViewController : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableViewOutlet.dequeueReusableCell(withIdentifier: "MyCell") as! MyCell
cell.lblData.text = data[indexPath.row]
return cell
}
}
extension FirstViewController: PassingProtocol {
func saveData(withText myText: String) {
data.append(myText)
DispatchQueue.main.async {
self.tableViewOutlet.reloadData()
}
}
}
SecondViewController.Swift
import UIKit
class SecondViewController: UIViewController {
#IBOutlet weak var textFieldData: UITextField!
var textDelegate: PassingProtocol!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func addEntryButtonAction(_ sender: Any) {
textDelegate.saveData(withText: textFieldData.text!)
}
}
PassingProtocol.Swift
import Foundation
protocol PassingProtocol {
func saveData(withText myText: String)
}
MyCell.Swift
import UIKit
class MyCell: UITableViewCell {
#IBOutlet weak var lblData: UILabel!
}
It will works , I've tried it myself and worked fine
After taking photo from a gallery. pass a delegate function to FirstVC.
FirstVC - function contain the data and Data count. Load Tableview in a dispatch queue method.
I am new in programming, and have problem. I am using parse for my array in tableview. When the row is selected i want to segue on another view controller to textView. The tableview works good but i can't get text to textView.
tableVC:
import UIKit
import Parse
class ThirdTableVC: UITableViewController {
#IBOutlet weak var refresherQuotes: UIRefreshControl!
#IBOutlet var quoteTable: UITableView!
var selectedQuote: PFObject?
var quoteItems = [PFObject]()
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func updateQuotesResults(_ sender: UIRefreshControl) {
fetchQuotesData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadQuoteTexts(selectedQuote: selectedQuote)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return quoteItems.count
}
func fetchQuotesData() {
let quotesQuery = PFQuery(className: "TotalTest")
quotesQuery.whereKey("Subcategory", equalTo: selectedQuote ?? nil)
quotesQuery.findObjectsInBackground { (objects, error) in
if let realCategoryObjects = objects {
self.quoteItems = realCategoryObjects
self.tableView.reloadData()
self.refresherQuotes.endRefreshing()
}
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let quoteCell = tableView.dequeueReusableCell(withIdentifier: "quoteCell", for: indexPath)
let quoteItem = quoteItems[indexPath.row]
let quoteUserTitle = quoteItem.object(forKey: "TextQuote") as? String
quoteCell.textLabel?.text = quoteUserTitle
return quoteCell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showQuoteDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let quoteobject = quoteItems[indexPath.row] as? NSDate
let quoteController = (segue.destination as! UINavigationController).topViewController as! DetailViewController
quoteController.detailItem = quoteobject
quoteController.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
quoteController.navigationItem.leftItemsSupplementBackButton = true
}
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Row tapped: \(indexPath.row)")
let selectedQuotes: PFObject = quoteItems[indexPath.row]
let FourthVC = self.storyboard?.instantiateViewController(withIdentifier: "FourthViewController") as! FourthViewController
FourthVC.fourthTextView.text = quoteItems[indexPath.row] as? String
self.navigationController?.pushViewController(FourthVC, animated: true)
}
func loadQuoteTexts(selectedQuote: PFObject!) {
let quoteQuery = PFQuery(className: "TotalQuote")
quoteQuery.whereKey("QuoteSubs", equalTo: selectedQuote ?? nil)
quoteQuery.includeKey("QuoteSubs")
quoteQuery.findObjectsInBackground { (result: [PFObject]?, error) in
if let searchQuoteResults = result {
self.quoteItems = searchQuoteResults
self.quoteTable.reloadData()
}
}
}
}
How can I change this?
viewController with textView:
import UIKit
import Parse
class FourthViewController: UIViewController {
var getQuote: PFObject?
#IBOutlet weak var fourthTextView: UITextView!
#IBOutlet weak var fourthLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
fourthLabel.text! = getQuote as! String
fourthTextView.text! = getQuote as! String
}
}
Please help me to passing texts
If you use pushViewController do it like that , in did selectRowAt
let MainStory: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let desVC = MainStory.instantiateViewController(withIdentifier: "FourthViewController") as! FourthViewController
and now pass your text
desVC.getText = "here goes your text u want to pass"
FourthViewController
set up your var
var getText = String()
so you can finally use
self.navigationController?.pushViewController(desVC, animated: true)
so it will pass all parameters you previous add with desVC.getSomething
in FourthViewController you just need to use getText.
The problem is that you are changing from a view to another with pushViewController, by doing that your prepareForSegue won't be executed.
On your didSelectRow you need to call performSegue(withIdentifier:sender:).
You can lookup this question for more information on how to do it.
I have a ViewController with two UIButtons and UIlabels.
In order to make similar ViewController of this, I would like to instantiate a new view controller programmatically
like this.
let vc = storyboard.instantiateViewControllerWithIdentifier("Main")
Then navigate to the view controller like this:
navigationcontroller?.pushViewController(vc, animated: true)
I have set StoryBoard ID as "Main", however I do not know where I can write these codes.
class ViewController: UIViewController, AVAudioPlayerDelegate {
let url1 = Bundle.main.bundleURL.appendingPathComponent("music1.mp3")
let url2 = Bundle.main.bundleURL.appendingPathComponent("music2.mp3")
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var yourButton1: customButton!
#IBOutlet weak var yourButton2: customButton!
override func viewDidLoad() {
super.viewDidLoad()
label1.text = "Hello1"
label2.text = "Hello2"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func player(url: URL) {
do {
try player = AVAudioPlayer(contentsOf:url)
player.play()
} catch {
print(error)
}
}
#IBAction func pushButton1(sender: UIButton) {
player(url: url1)
}
#IBAction func pushButton2(sender: UIButton) {
player(url: url2)
}
}
tableView
class SecondTableViewController: UITableViewController {
var names = [String]()
var identities = [String]()
override func viewDidLoad() {
names = ["name1","name2","name3","name4"]
identities = ["Main","Main2","Main3","Main4"]
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
let label1 = cell?.viewWithTag(1) as! UILabel
label1.text = "\(names[indexPath.row])"
return cell!
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vcName = identities[indexPath.row]
let ViewController = storyboard?.instantiateViewController(withIdentifier: vcName)
self.navigationController?.pushViewController(ViewController!, animated: true)
}
}
You need to set Storyboard ID value for the view controller in storyboard and use it here:
let storyboard = UIStoryboard(name: "StoryboardName", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RegistrationController")
navigationcontroller?.pushViewController(vc, animated: true)
Edit:
var urls1 = [String]()
var urls2 = [String]()
override func viewDidLoad() {
names = ["name1","name2","name3","name4"]
identities = ["A","B","C","D"]
urls1 = ["url1","url2" ....]
urls2 = ["url1","url2" ....]
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let url1 = urls1[indexPath.row]
let url2 = urls2[indexPath.row]
//let ViewController = storyboard?.instantiateViewController(withIdentifier: vcName) this is wrong you only have one viewcontroller on storyboard and its storyboard id is fixed.
let viewController: ViewController = storyboard?.instantiateViewController(withIdentifier: "StoryboardID") as! ViewController
viewController.url1 = url1
viewController.url2 = url2
self.navigationController?.pushViewController(ViewController!, animated: true)
}
I know it's kinda frequently ask question, but I did some research and none of the solutions work.
so here's my controller with table view
class MainPage: UIViewController, UITableViewDelegate, UITableViewDataSource, YoubikeManagerDelegate {
#IBOutlet weak var tableView: UITableView!
let mainPageCell = MainPageCell()
let mapPage = MapViewController()
var stations: [Station] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "infoCell") as! MainPageCell
cell.stationNameLabel.text = stations[indexPath.row].name
cell.stationLocationLabel.text = stations[indexPath.row].address
cell.numberOfRemainingBikeLabel.text = stations[indexPath.row].numberOfRemainingBikes
cell.printer = stations[indexPath.row].name
cell.mapBtn.tag = indexPath.row
cell.mapBtn.addTarget(self, action: #selector(moveToMapPage), for: .touchUpInside)
return cell
}
func moveToMapPage(sender: UIButton) {
self.performSegue(withIdentifier: "toMap", sender: self)
let nameToPass = stations[sender.tag].name
mapPage.stationName = nameToPass
}
}
there is a UIButton in my tableView cell
class MainPageCell: UITableViewCell {
var printer: String!
let mapPage = MapViewController()
#IBOutlet weak var stationNameLabel: UILabel!
#IBOutlet weak var mapBtn: UIButton!
#IBOutlet weak var stationLocationLabel: UILabel!
#IBOutlet weak var numberOfRemainingBikeLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
mapBtn.addTarget(self, action: #selector(mapBtnTapped), for: .touchUpInside)
}
func mapBtnTapped (sender: UIButton) {
print (printer)
}
}
and this is my other vc
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var stationName: String = ""
override func viewDidLoad() {
super.viewDidLoad()
self.title = stationName
}
}
I will elaborate my problem that i am now facing here !
the thing I want to do is when I tap the button in tableView cell, I want to go to MapViewController and make the title of this vc "the station name" in the same cell.
so in VC with tableView, in cellforRowAt function I called addTarget.
with moveToMapPage function
but when I tapped the button and goes to MapView VC, the stationName is still nil
I have no clue what goes wrong,
any hints are appreciated
mapPage is not the instance that you are navigating to, so you're setting a variable on an unrelated controller.
You need to use prepare(for segue... if you want to get a link to the new controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
// if you have multiple segues, you can set up different actions for each
if segue.identifier == "segueToMap"
{
let mapPage : MapViewController = segue.destination as! MapViewController
let mapPage : MapViewController = segue.destination as! MapViewController
mapPage.stationName = nameToPass
mapPage.delegate = self // if required
}
}
use navigation controller
let vc = self.storyboard?.instantiateViewController(withIdentifier:"toMap") as! toMapViewController
vc.stationNam = stations[sender.tag].name
self.navigationController?.pushViewController(vc, animated: true)
I have this JSON data
move.json
{
"status":"ok",
"movement":
[
{
"refno":"REF 1",
"dtfrom":"2017-13-12"
},
{
"refno":"REF 2",
"dtfrom":"2017-13-13"
},
{
"refno":"REF 3",
"dtfrom":"2017-13-14"
},
]
}
So far, I managed to fetch the value into TableViewCell.
But my goal is to pass the value from ViewController.swift into MoveDetails.swift so the value can be display in MoveDetails.swift
And I have these four swift files. I'm having the problem on ViewController.swift and MoveDetails.swift. I'm not sure how to pass the value into new Controller.
The code as below.
ViewController.swift
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableview: UITableView!
var move: [Move]? = []
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
}
func fetchData() {
let urlRequest = URLRequest(url: URL(string: "http://localhost/move.json")!)
let task = URLSession.shared.dataTask(with: urlRequest) {
(data,response,error)in
if error != nil { return }
self.move = [Move]()
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject]
if let msFromJson = json["movement"] as? [[String: AnyObject]] {
for mFromJson in msFromJson {
let ms = Move()
if let refno = mFromJson["refno"] as? String, let dtfrom = mFromJson["dtfrom"] as? String {
ms.refno = refno
ms.dtfrom = dtfrom
}
self.move?.append(ms)
}
}
DispatchQueue.main.async {
self.tableview.reloadData()
}
}
catch let error{ print(error)}
}
task.resume()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "movementstatusCell", for: indexPath) as! MoveCell
cell.refnoLbl.text = self.move?[indexPath.item].refno
cell.dtfromLbl.text = self.move?[indexPath.item].dtfrom
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.move?.count ?? 0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "MoveDetails") as! MoveDetails
let selectedMove = self.move?[indexPath.item]
vc.refnoString = selectedMove.refno
vc.dtfromString= selectedMove.dtfrom
self.navigationController?.pushViewController(vc, animated: true)
}
}
MoveCell.swift
import UIKit
class MoveCell: UITableViewCell {
#IBOutlet weak var dtfromLbl: UILabel!
#IBOutlet weak var refnoLbl: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
Move.swift (NSObject)
import UIKit
class Move: NSObject {
var refno: String?
var dtfrom: String?
}
MoveDetails.swift
import UIKit
class MoveDetails: UIViewController {
#IBOutlet weak var refnoLbl: UILabel!
#IBOutlet weak var dtfromLbl: UILabel!
var refnoString: String!
var dtfromString: String!
override func viewDidLoad() {
super.viewDidLoad()
refnoString = refnoLbl.text
dtfromString = dtfromLbl.text
}
override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() }
}
Appreciate if someone can help. Thanks.
You will just have to set the properties of your MoveDetails view controller. And as a suggestion
Instead of storing refnoString and dtfromString properties in MoveDetails, you could just store one property of type Move:
Cache MoveDetails view controller to reuse it
Implement viewDidAppear to update the MoveDetails outlets
So:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var detailsVC : MoveDetails?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if (detailsVC == nil) {
detailsVC = self.storyboard?.instantiateViewController(withIdentifier: "MoveDetails") as! MoveDetails
}
detailsVC.move = self.move?[indexPath.item]
self.navigationController?.pushViewController(detailsVC , animated: true)
}
}
Then, override viewDidAppear in MoveDetails view controller and there you just fill in the values into the text label outlets.
class MoveDetails: UIViewController {
#IBOutlet weak var refnoLbl: UILabel!
#IBOutlet weak var dtfromLbl: UILabel!
var move:Move?
override func func viewDidAppear(_ animated: Bool) {
refnoLbl.text = move?.refno
dtfromLbl.text = move?.dtfrom
}
}
Syntax errors cause because I currently have no Xcode available to do the checking