您将如何从子视图中呈现 ViewController?
How would you presentViewController from subview?
假设我们有一个自定义控件,在某些状态下应该弹出选项列表供用户选择 (UIAlertController)。通常当我们在视图控制器中时,我们使用 presentViewController 方法,但在这种情况下,我们无法访问持有此方法的父级 UIViewController。虽然似乎有一些方法可以从子视图访问 UIViewController,但它被认为是违反 MVC 设计模式的。那你会怎么做呢?
我想让视图控制器尽可能精简,自定义视图 (uicontrol) 自给自足,所以我不想将此逻辑移动到视图控制器。
尽管欢迎和赞赏您的所有意见和建议。
您始终可以使用应用程序 rootviewController 来显示您的警报视图控制器:)您不必总是选择视图控制器的视图:)无论您的控件在哪里,rootview 控制器始终可以访问:)
您可以执行以下操作:)
Objective C
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.window.rootViewController presentViewController:your_alert_view_controller animated:YES completion:nil];
Swift
let appDelegate : AppDelegate? = UIApplication.sharedApplication().delegate as? AppDelegate
if let unwrappedAppdelegate = appDelegate {
unwrappedAppdelegate.window!.rootViewController! .presentViewController(alert, animated: true, completion: nil)
}
希望我的回答对你有所帮助:)
我更喜欢委派或目标行动。这是一种更简洁的方法,因为在这种情况下您不使用 AppDelegate
。显示某些内容也不是子视图的责任。授权示例:
protocol MyViewDelegate: class {
func somethingHappenedToMyView(view: MyView)
}
class MyView: UIView {
weak var delegate: MyViewDelegate?
func somethingHappened() {
delegate?.somethingHappenedToMyView(self)
}
}
class ViewController: UIViewController, MyViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
myView.delegate = self
}
func somethingHappenedToMyView(view: MyView) {
presentViewController(someViewController, animated: true, completion: nil)
}
}
目标操作示例:
class MyView: UIControl {
func somethingHappened() {
sendActionsForControlEvents(.ValueChanged) // .ValueChanged is an example. Maybe other events will be more meaningful for your situation
}
}
class ViewController: UIViewController, MyViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
myView.addTarget(self, action: #selector(self.somethingHappenedToMyView(_:)), forControlEvents: .ValueChanged)
}
func somethingHappenedToMyView(view: MyView) {
presentViewController(someViewController, animated: true, completion: nil)
}
}
从委托根视图控制器呈现在许多情况下都不起作用(嵌套呈现、选项卡的更多控制器等)。
最好通过遍历视图的响应者链来找到父 UIViewController 响应者。使用这个宏:
#define UIViewParentController(__view) ({ \
UIResponder *__responder = __view; \
while ([__responder isKindOfClass:[UIView class]]) \
__responder = [__responder nextResponder]; \
(UIViewController *)__responder; \
})
在视图中:
UIViewController *parentViewController = UIViewParentController(self);
相关问题:one, two.
假设我们有一个自定义控件,在某些状态下应该弹出选项列表供用户选择 (UIAlertController)。通常当我们在视图控制器中时,我们使用 presentViewController 方法,但在这种情况下,我们无法访问持有此方法的父级 UIViewController。虽然似乎有一些方法可以从子视图访问 UIViewController,但它被认为是违反 MVC 设计模式的。那你会怎么做呢? 我想让视图控制器尽可能精简,自定义视图 (uicontrol) 自给自足,所以我不想将此逻辑移动到视图控制器。 尽管欢迎和赞赏您的所有意见和建议。
您始终可以使用应用程序 rootviewController 来显示您的警报视图控制器:)您不必总是选择视图控制器的视图:)无论您的控件在哪里,rootview 控制器始终可以访问:)
您可以执行以下操作:)
Objective C
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.window.rootViewController presentViewController:your_alert_view_controller animated:YES completion:nil];
Swift
let appDelegate : AppDelegate? = UIApplication.sharedApplication().delegate as? AppDelegate
if let unwrappedAppdelegate = appDelegate {
unwrappedAppdelegate.window!.rootViewController! .presentViewController(alert, animated: true, completion: nil)
}
希望我的回答对你有所帮助:)
我更喜欢委派或目标行动。这是一种更简洁的方法,因为在这种情况下您不使用 AppDelegate
。显示某些内容也不是子视图的责任。授权示例:
protocol MyViewDelegate: class {
func somethingHappenedToMyView(view: MyView)
}
class MyView: UIView {
weak var delegate: MyViewDelegate?
func somethingHappened() {
delegate?.somethingHappenedToMyView(self)
}
}
class ViewController: UIViewController, MyViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
myView.delegate = self
}
func somethingHappenedToMyView(view: MyView) {
presentViewController(someViewController, animated: true, completion: nil)
}
}
目标操作示例:
class MyView: UIControl {
func somethingHappened() {
sendActionsForControlEvents(.ValueChanged) // .ValueChanged is an example. Maybe other events will be more meaningful for your situation
}
}
class ViewController: UIViewController, MyViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
myView.addTarget(self, action: #selector(self.somethingHappenedToMyView(_:)), forControlEvents: .ValueChanged)
}
func somethingHappenedToMyView(view: MyView) {
presentViewController(someViewController, animated: true, completion: nil)
}
}
从委托根视图控制器呈现在许多情况下都不起作用(嵌套呈现、选项卡的更多控制器等)。
最好通过遍历视图的响应者链来找到父 UIViewController 响应者。使用这个宏:
#define UIViewParentController(__view) ({ \
UIResponder *__responder = __view; \
while ([__responder isKindOfClass:[UIView class]]) \
__responder = [__responder nextResponder]; \
(UIViewController *)__responder; \
})
在视图中:
UIViewController *parentViewController = UIViewParentController(self);
相关问题:one, two.