我遇到过一个子视图包含一个关闭它的按钮的情况。我发出警报以确认操作。它向代表(包含子视图的视图控制器)发送消息以删除子视图
最初我从一个 UIView 中展示了一个 UIAlertView。重构 UIAlertController,因为 UIAlertController 不能像 UIAlertView 那样呈现自己,我想出了以下内容(在 Swift 中;很容易翻译为 ObjC):
向子视图添加协议:
protocol MySubviewDelegate {
// called when user taps subview/delete button
// or, you could call it from a gesture handler, etc.
func displayAlert(alert : UIAlertController)
// called when user confirms delete from the alert controller
func shouldRemoveSubview(sender : AnyObject)
}
为子视图添加一个委托,并为按钮/手势点击添加一个处理程序:
class MySubview : UIView {
var subviewDelegate : MySubviewDelegate!
...
func handleTap(sender : AnyObject) {
// set up the alert controller here
var alert = UIAlertController(title: "Confirm Delete",
message: "This action is permanent. Do you wish to continue?",
preferredStyle: UIAlertControllerStyle.Alert)
// Cancel action
// nil handler means "no action if Cancel button selected"
alert.addAction(UIAlertAction(title: "Cancel",
style: UIAlertActionStyle.Cancel,
handler: nil))
// Confirm action
alert.addAction(UIAlertAction(title: "Confirm",
style: UIAlertActionStyle.Default,
handler: { (action : UIAlertAction!) -> Void in
// call delegate method to perform confirmed action, - i.e. remove
self.subviewDelegate.shouldRemoveSubview(self)
}))
// call delegate method to display alert controller
// send alert object to delegate
self.subviewDelegate.displayAlert(alert)
}
}
将调用 UIViewController 设置为子视图的委托,例如,在其 viewDidLoad() 方法中,并包含协议方法:
class viewController : UIViewController, MySubviewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.subviewDelegate = self
...
}
func displayAlert(alert : UIAlertController) {
presentViewController(alert, animated: true, completion: nil)
}
func shouldRemoveSubview(sender : AnyObject) {
// cast as UIView / MySubview subclass
var subview = sender as MySubview
// remove the subview / perform the desired action
subview.removeFromSuperview()
...
}
...
}
这避免了查找最顶层视图控制器的需要,或将视图控制器的引用传递给子视图(对象/委托关系除外)。