Swift - 如何将视图控制器的引用传递给子 UIView 类?
Posted
技术标签:
【中文标题】Swift - 如何将视图控制器的引用传递给子 UIView 类?【英文标题】:Swift - How to pass a view controller's reference to a sub UIView class? 【发布时间】:2014-07-06 09:00:51 【问题描述】:我里面有一个 UIViewController 和一个 UIView。当我尝试在 UIView 中添加警报时,我必须使用控制器来呈现 UIAlertController。如何将 UIViewController 的引用传递给 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)
【问题讨论】:
你看到这个答案了吗:***.com/a/3732812/2468186? 这看起来与您之前的问题How to create an alert in a subview class in Swift? 相同(您接受了答案)。 @MartinR 我将这个问题发布到一个更通用的问题,即如何从子 UIView 引用父控制器。这可能对正在寻找此类主题的其他人有所帮助 【参考方案1】:按照 MVC 模式,ViewController 知道它的 View,但 View 不应该知道 ViewController。相反,您应该为您的ViewController
采用的GameBoardUIView
声明委托协议,如下所示:
// 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)
【讨论】:
感谢您的链接。关于您的代码,我有两个问题。首先是我们在哪里分配委托值?默认情况下它是 nil ,对吗?第二个问题是,我注意到您将@IBOutlet var gameBoardUIView: GameBoardUIView
替换为let gameView = GameBoardUIView()
,这是如何工作的?
现在说得通了。除了弱引用不起作用。我将在self.delegate?.checkIfNextMoveExistsForGameBoardUIView(gameBoardUIView: self)
收到 EXC_BAD_ACCESS 异常。如果我使用普通参考,它可以成功弹出警报。
谢谢你,对一个视图控制器工作得很好,但是有没有办法让它在多个视图控制器中工作而不重复代码?使用 AppDelegate?还是 UIViewController 的扩展?【参考方案2】:
或者,您也可以从 .xib 发布通知并让父视图控制器观察它。您将能够在发布期间通过 userInfo 对象发送数据。
【讨论】:
以上是关于Swift - 如何将视图控制器的引用传递给子 UIView 类?的主要内容,如果未能解决你的问题,请参考以下文章
选择时将值从 TabBarController 传递给子视图控制器
如何将值从 NSTabViewController 传递给子视图?