2016-07-05 7 views
0

Ich habe, was im Grunde eine Notizen-App ist, und ich versuche, eine Funktion, die in einem View-Controller aus einem anderen aufgerufen wird. Wie mache ich das, oder gibt es einen besseren Weg, ich sollte es tun?Wie rufe ich eine Funktion von einem anderen View-Controller auf?

Hier ist, wo ich versuche, um die Funktion von

class NoteDetailViewController: UIViewController 
{ 
    @IBOutlet weak var funcButton: UIButton! 

    @IBAction func funcButTouched(sender: UIButton) 
    { 
    // where i want to call the function 
    } 
} 

zu nennen Und wo die Funktion ist

class ListTableViewController: UITableViewController 
{ 
    // the function 
    func wordCount() 
    { 
     var contentArr = Project.sharedInstance.content.componentsSeparatedByString(" ") 
     for (index, element) in contentArr.enumerate() 
     { 
      let location = conciseArr.indexOf(element) 
      if (location != nil) 
      { 
       contentArr[index] = inflatedArr[location!] 
       afterStr = contentArr.joinWithSeparator(" ") 
       Project.sharedInstance.after = afterStr 
      } 
     } 
    } 
} 

Ich habe versucht, nur eine Instanz von ListTableViewController Erstellen und ruft nur die Funktion, die Art und Weise aber ich bekomme einen Fehler.

+0

Ich bin nicht sicher, ich verstehe, was Sie fragst du? –

+0

Können Sie mir Ihre UIViewController-Hierarchie zeigen? –

+0

Die Reihenfolge meiner View-Controller? Es geht ListTableViewController zu NoteDetailViewController –

Antwort

1

Sie könnten delegation verwenden.

Zuerst ein Delegate-Protokoll deklarieren. Dies sollte in Ihrer NoteDetailViewController.swift Datei sein, aber außerhalb der class Erklärung:

protocol NoteDetailViewControllerDelegate: class { 
    func noteDetailViewControllerButtonTouched(controller: NoteDetailViewController) 
} 

Als nächstes einen Delegaten Eigenschaft zu Ihrem NoteDetailViewController hinzufügen:

weak var delegate: NoteDetailViewControllerDelegate? 

Jetzt verwenden wir die @IBAction den Delegierten zu sagen, was wird die ListTableViewController:

@IBAction func funcButTouched(sender: UIButton) 
{ 
    delegate?.noteDetailViewControllerButtonTouched(self) 
} 

schließlich in ListTableViewController, zurück (assum ing diesen Controller wird direkt die vor einem NoteDetailViewController) gezeigt wird, entsprechen prepareForSegue das Protokoll und verwenden Sie die Delegierten selbst zu setzen:

class ListTableViewController: UITableViewController, NoteDetailViewControllerDelegate { 
    // ... more stuff ... 

    // Implement the delegate protocol 
    func noteDetailViewControllerButtonTouched(controller: NoteDetailViewController) { 
     // Do something! The button was pressed! 
     wordCount() 
    } 
    // Set ourselves as delegate when we are about to show the other view controller 
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     if let yourVC = segue.destinationViewController as? NoteDetailViewController { 
      yourVC.delegate = self 
     } 
    } 
} 

Sie mit so etwas wie diesem beenden sollten:

NoteDetailViewController.swift:

class NoteDetailViewController: UIViewController 
{ 
    @IBOutlet weak var funcButton: UIButton! 
    weak var delegate: NoteDetailViewControllerDelegate? 

    @IBAction func funcButTouched(sender: UIButton) 
    { 
     delegate?.noteDetailViewControllerButtonTouched(self) 
    } 
} 

protocol NoteDetailViewControllerDelegate: class { 
    func noteDetailViewControllerButtonTouched(controller: NoteDetailViewController) 
} 

ListTableViewController.swift:

class ListTableViewController: UITableViewController, NoteDetailViewControllerDelegate 
{ 
    // the function 
    func wordCount() 
    { 
     var contentArr = Project.sharedInstance.content.componentsSeparatedByString(" ") 
     for (index, element) in contentArr.enumerate() 
     { 
      let location = conciseArr.indexOf(element) 
      if (location != nil) 
      { 
       contentArr[index] = inflatedArr[location!] 
       afterStr = contentArr.joinWithSeparator(" ") 
       Project.sharedInstance.after = afterStr 
      } 
     } 
    } 
    // Implement the delegate protocol 
    func noteDetailViewControllerButtonTouched(controller: NoteDetailViewController) { 
     // Do something! The button was pressed! 
     wordCount() 
    } 
    // Set ourselves as delegate when we are about to show the other view controller 
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     if let yourVC = segue.destinationViewController as? NoteDetailViewController { 
      yourVC.delegate = self 
     } 
    } 
} 
+0

Auf der 'yourVC.delegate = self' Zeile bekomme ich den Fehler" Kann keinen Wert des Typs 'ListTableViewController' auf 'NoteDetailViewControllerDelegate?'' –

+0

@SetRodgers hast du vergessen, die Klassendeklaration zu ändern? Überprüfe die erste Zeile. –

+0

Ja! Aber jetzt, wenn alles funktioniert, zeigt 'Project.sharedInstance.after' nicht die afterStr. Ich weiß, dass es den Wert bekommt, aber es zeigt es einfach nicht an. –

0

Folgen Sie einfach unten Code seiner sehr einfachen: -

NoteDetailViewController.swift:

class NoteDetailViewController: UIViewController 
{ 
    @IBOutlet weak var funcButton: UIButton! 

    var parentListTableView : ListTableViewController! 
    @IBAction func funcButTouched(sender: UIButton) 
    { 
     parentListTableView.wordCount() 

    } 
} 

ListTableViewController.swift:

class ListTableViewController: UITableViewController 
{ 
    // the function 
    func wordCount() 
    { 
     var contentArr = Project.sharedInstance.content.componentsSeparatedByString(" ") 
     for (index, element) in contentArr.enumerate() 
     { 
      let location = conciseArr.indexOf(element) 
      if (location != nil) 
      { 
       contentArr[index] = inflatedArr[location!] 
       afterStr = contentArr.joinWithSeparator(" ") 
       Project.sharedInstance.after = afterStr 
      } 
     } 
    } 

    // Set ourselves as delegate when we are about to show the other view controller 
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     if let yourVC = segue.destinationViewController as? NoteDetailViewController { 
      yourVC.parentListTableView = self 
     } 
    } 
} 
+0

Dies würde funktionieren, aber erzwingt die Notwendigkeit für' WordCount ', um öffentlich zu bleiben. Delegierung ermöglicht es jedem Ansichtscontroller, die Kontrolle über seine eigenen Funktionen zu behalten und anderen Sichtsteuerungen nicht zu erlauben, sie zu missbrauchen. –

+1

Sie haben Recht, aber nehmen Sie an, nur für eine View-Controls zu verwenden, dann müssen Sie das Protokoll verwenden, deshalb schlage ich dies vor. –

Verwandte Themen