2016-04-07 14 views
0

Ich habe die folgende Klasse unten. Die Idee ist, dass ein benutzerdefinierter Progress Window View Controller verwendet wird, um den Fortschritt verschiedener Ereignisse zu verarbeiten. Das Problem ist, da dies in einer Klasse und nicht ein View-Controller ist es selbst, ich bin mir nicht sicher, wie man das progressWindow tatsächlich zeigen, nachdem ich es aus dem Storyboard instanziieren?Wie kann der View Controller sich selbst darstellen?

Wie mache ich das? Momentan bekomme ich einen Fehler, dass die Anwendung versucht hat, den Model-View-Controller auf sich selbst zu präsentieren.

import Foundation 
import UIKit 

class StatusProgress{ 
    static var cancelCode = {} 
    static var runCode = {} 
    static var theProgressWindowController = ProgressWindowViewController() 
    static var returningViewControllerIdentifier = "" 
    static let storyboard = UIStoryboard(name: "Main", bundle: nil) 

    static func run(){ 
     // This will run in parralel but on main queue. Has to be on this Queue because it might involve UI 
     dispatch_async(dispatch_get_main_queue(), { 
      // Update the UI on the main thread. 
      StatusProgress.runCode() 
     }); 

    } 

    static func cancel(){ 
     dispatch_async(dispatch_get_main_queue(), { 
      StatusProgress.cancelCode() 
      dispatch_sync(dispatch_get_main_queue(),{ 
       let storyboard = UIStoryboard(name: "Main", bundle: nil) 
       let vc = storyboard.instantiateViewControllerWithIdentifier(returningViewControllerIdentifier) 
       vc.presentViewController(vc, animated: true, completion: nil) 
      }) 
     }); 
    } 

    static func show(){ 
     dispatch_async(dispatch_get_main_queue(),{ 
      theProgressWindowController = self.storyboard.instantiateViewControllerWithIdentifier("progressWindow") as! ProgressWindowViewController 
      theProgressWindowController.presentViewController(theProgressWindowController, animated: true, completion: nil) //use own instance to show it's self? (throws error! application tried to present modal view controller on itself. Presenting controller is <Inventory_Counter.ProgressWindowViewController: 0x1466ea390>.') 
     }) 
    } 
} 

Mein Problem ist im Wesentlichen brauche ich einen Ersatz für diese Codezeile.

theProgressWindowController.presentViewController(theProgressWindowController, animated: true, completion: nil) 

ich hier vergessen zu erwähnen ist der Code, der es in einem anderen View-Controller läuft.

SyncViewController.swift

import UIKit 

class SyncViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Do any additional setup after loading the view. 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    @IBAction func yesSyncButtonAction(sender: UIButton) { 
     StatusProgress.returningViewControllerIdentifier = "syncWindow" 
     StatusProgress.runCode = { 
      print("run code test") 
     } 
     StatusProgress.cancelCode = { 
      print("cancel code test") 
     } 
     StatusProgress.show() 
    } 

    @IBAction func noSyncActionButton(sender: UIButton) { 
     tabBarController?.selectedIndex = 1 //assume back to inventory section 
    } 

    /* 
    // MARK: - Navigation 

    // In a storyboard-based application, you will often want to do a little preparation before navigation 
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     // Get the new view controller using segue.destinationViewController. 
     // Pass the selected object to the new view controller. 
    } 
    */ 

} 

Antwort

3

Das größte Problem ist, dass Ihre StatusProgress Klasse instanziieren und zeigt eine Ansicht zu entfernen. View-Controller sollten andere View-Controller instanziieren und anzeigen, Modellobjekte dagegen nicht. Sie müssen also die Logik zum Präsentieren des neuen View-Controllers in Ihre SyncViewController verschieben. Verwenden Sie dann die Delegierung, um mit der SyncViewController zu kommunizieren, dass die Synchronisierung abgeschlossen ist.

protocol StatusProgressDelegate { 
    func statusProgress(status: StatusProgress, shouldShow: Bool) 
    func statusProgress(status: StatusProgress, shouldCancel: Bool) 
} 

Ihr StatusProgress Objekt würde einen Delegierten, die zu diesem Protokoll entspricht und rufen Sie diesen Delegaten innerhalb seiner Show und kündigen Methoden. Dies bedeutet, dass Sie die Instanzmethoden der statischen Funktionen erstellen und einen Initialisierer für die Klasse schreiben müssen, damit Sie sie instanziieren können.

+0

Wie würde ich die Delegiertenmeldungen senden? Das ist eine interessante Idee und ich mag sie. Kannst du mit Beispiel wenn möglich updaten? –

+0

Dies ist ein super einfaches iOS Designmuster. Wenn Sie jemals Tabellenansichten oder Auflistungsansichten verwendet haben, haben Sie dieses Muster bereits verwendet. Sie senden die Delegat-Nachrichten, indem Sie die Funktionen aufrufen, die in dem Protokoll für das Delegat-Objekt aufgelistet werden. Sie können weitere Informationen hier finden: https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html –

+0

Ich bin mir nicht sicher, warum das so schwer für mich ist, herauszufinden . Ich bekomme Delegierte aber nicht sicher, wie man es in dieser Situation benutzt. Ich werde es seit 8 Stunden immer wieder versuchen :). Ich werde meine Antwort posten, wenn es funktioniert und akzeptiere das bald. –

0

Wenn die Ansicht Lebenszyklusereignisse sind für Sie nicht viel wichtiger, können Sie nur den Blick auf Ihren Fortschritt Controller Ansicht Ihrer aktuellen Controller hinzuzufügen. oder es ist noch besser, wenn Sie den UIView-Parameter in Ihrer show()-Funktion angeben.

static func show(attachToView: UIView){ 
     dispatch_async(dispatch_get_main_queue(),{ 
      theProgressWindowController = self.storyboard.instantiateViewControllerWithIdentifier("progressWindow") as! ProgressWindowViewController 
      attachToView.addSubview(theProgressWindowController.view) 
     }) 
    } 

Schließlich sollten Sie Ihre Fortschritte Ansicht von Superview Controller

static func cancel(){ 
      dispatch_async(dispatch_get_main_queue(),{ 
       theProgressWindowController = self.storyboard.instantiateViewControllerWithIdentifier("progressWindow") as! ProgressWindowViewController 
       theProgressWindowController.view.removeFromSuperview() 
      }) 
     } 
+0

Dies ist auch eine interessante Taktik. Glaubst du, die obige Antwort von Chandler ist besser, heximal zu gehen, oder ist die Art, wie du es beschrieben hast, immer noch gut? –

+0

Wie du bereits erwähnt hast, ist deine Fortschrittssteuerung kein richtiger Controller, also denke ich, dass mein Ansatz brauchbar ist. Ich kann sogar mit derselben Taktik auf ähnliche Kontrolle zeigen. Hier ist es [MBProgressHUD] (https://github.com/jdg/MBProgressHUD) – heximal

Verwandte Themen