2014-07-06 23 views
9

我有一個UIViewController和一個UIView裏面。當我嘗試在UIView中添加警報時,我必須使用控制器來呈現UIAlertController。如何將UIViewController的引用傳遞給UIView類?或者,我該如何創建一個控制器委託?Swift - 如何將視圖控制器的引用傳遞給子UIView類?

class GameViewController: UIViewController { 
    @IBOutlet var gameBoardUIView: GameBoardUIView 
    ... 
} 

class GameBoardUIView: UIView { 
    ... 
    func move() { 
     if !gameBoard.checkNextMoveExist() { 
      var alert = UIAlertController(title: "Game Over", message: nil, preferredStyle: UIAlertControllerStyle.Alert) 
      alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Cancel, handler: {(action: UIAlertAction!) in 
       println("Game Over") 
      })) 
      })) 
      // Following would fail because self is not a UIViewController here 
      // self.presentViewController(alert, animated: true, completion: nil) 
     } 
    } 
} 
+0

你有沒有看到這個答案:http://stackoverflow.com/a/3732812/2468186? –

+0

這看起來和你以前的問題是一樣的[如何在Swift中的子視圖類中創建警報?](http://stackoverflow.com/questions/24584364/how-to-create-an-alert-in-a-subview迅速)(你接受了答案)。 –

+1

@MartinR我發佈這個問題的更通用的問題是如何從子UIView引用父控制器。對於正在尋找此類主題的其他人可能會有幫助 – Bing

回答

15

繼MVC模式,一個視圖控制器知道其意見,但查看不應該知道的視圖控制器。相反,你應該申報委託協議GameBoardUIViewViewController採用如下:

// Delegate protocol declared here 
protocol GameBoardUIViewDelegate: class { 
    func checkIfNextMoveExistsForGameBoardUIView(gameBoardUIView: GameBoardUIView) 
} 

class GameBoardUIView: UIView { 

    // GameBoardUIView has a delegate property that conforms to the protocol 
    // weak to prevent retain cycles 
    weak var delegate:GameBoardUIViewDelegate? 

    func move() { 
     if !gameBoard.checkNextMoveExist() { 
      delegate?.checkIfNextMoveExistsForGameBoardUIView(gameBoardUIView: self) 
     } 
    } 

} 

// View controller subclass adopts the protocol 
class GameViewController: UIViewController, GameBoardUIViewDelegate { 

    @IBOutlet var gameBoardUIView: GameBoardUIView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     gameBoardUIView.delegate = self 
    } 

    // Delegte protocol method 
    func checkIfNextMoveExistsForGameBoardUIView(gameBoardUIView: GameBoardUIView) { 

     let alert = UIAlertController(title: "Game Over", message: nil, preferredStyle: .alert) 

     alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: {(action: UIAlertAction!) in 
      print("Game Over") 
     })) 

     // If you need to feed back to the game view you can do it in the completion block here 
     present(alert, animated: true, completion: nil) 
    } 
} 
+0

感謝您的鏈接。我有兩個關於你的代碼的問題。首先是我們在哪裏分配委託值?它默認爲零,對不對?第二個問題是,我發現你用'let gameView = GameBoardUIView()'替換'@IBOutlet var gameBoardUIView:GameBoardUIView',這是如何工作的? – Bing

+0

對不起,我的錯。我更新了代碼。 –

+0

現在有道理。除了弱參考不起作用。 'self.delegate?.checkIfNextMoveExistsForGameBoardUIView(gameBoardUIView:self)'會得到一個EXC_BAD_ACCESS異常。如果我使用正常參考,它會在警報彈出成功時起作用。 – Bing

0

或者,你也可以從你的.xib張貼通知,並有視圖 - 控制觀察它的母公司。您將能夠在發佈期間通過userInfo對象發送數據。

相關問題