Skip to content

Commit 8a4ee62

Browse files
committed
Responder: improve the responder hierarchy configuration
This improves the responder hierarchy handling to be more correct. One of the largest changes occurs in the `ViewController` type which gains more of its interfaces. These are needed for presenting a view controller and to have the parent-child relationship for the view controllers. These impact the view hierarchy and thus must be present.
1 parent eee18de commit 8a4ee62

File tree

4 files changed

+62
-3
lines changed

4 files changed

+62
-3
lines changed

Sources/SwiftWin32/App and Environment/Application.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ open class Application: Responder {
4444

4545
// Responder Chain
4646
override public var next: Responder? {
47+
// The next responder is the application delegate, but only if the
48+
// application delegate is an instance of `Responder` and is not a `View`,
49+
// `ViewController`, or the `Application` object itself.
4750
if let responder = self.delegate as? Responder,
4851
!(self.delegate is View), !(self.delegate is ViewController),
4952
!(self.delegate === self) {

Sources/SwiftWin32/View Controllers/ViewController.swift

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,39 @@ public class ViewController: Responder {
280280
public func didMove(toParent viewController: ViewController?) {
281281
}
282282

283+
// MARK - Managing Child View Controllers in a Custom Controller
284+
285+
/// An array of view controllers that are children of the current view
286+
/// controller.
287+
public private(set) var children: [ViewController] = []
288+
289+
/// Adds the specified view controller as a child of the current view
290+
/// controller.
291+
public func addChild(_ controller: ViewController) {
292+
self.children.append(controller)
293+
controller.parent = self
294+
}
295+
296+
/// Removes the view controller from its parent.
297+
public func removeFromParent() {
298+
self.parent?.children.remove(object: self)
299+
self.parent = nil
300+
}
301+
302+
// MARK - Getting Other Related View Controllers
303+
304+
/// The view controller that presented this view controller.
305+
public private(set) var presentingViewController: ViewController?
306+
307+
/// The view controller that presented this view controller.
308+
public private(set) var presentedViewController: ViewController?
309+
310+
/// The view controller that presented this view controller.
311+
public private(set) var parent: ViewController? {
312+
willSet { self.willMove(toParent: newValue) }
313+
didSet { self.didMove(toParent: self.parent) }
314+
}
315+
283316
// MARK -
284317

285318
override public init() {
@@ -288,7 +321,18 @@ public class ViewController: Responder {
288321
// MARK - Responder Chain
289322

290323
override public var next: Responder? {
291-
return view?.superview
324+
// If the view controller's view is the root view of a window, the next
325+
// responder is the Window object.
326+
if self.view is Window { return view }
327+
// If the view controller is presented by another view controller, the next
328+
// responder is the presenting view controller.
329+
return self.presentingViewController
330+
}
331+
}
332+
333+
extension ViewController: Equatable {
334+
public static func ==(_ lhs: ViewController, _ rhs: ViewController) -> Bool {
335+
return lhs === rhs
292336
}
293337
}
294338

Sources/SwiftWin32/Views and Controls/View.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -921,8 +921,13 @@ public class View: Responder {
921921
// MARK - Responder Chain
922922

923923
public override var next: Responder? {
924-
if let parent = self.superview { return parent }
925-
return nil
924+
// If the view is the root view of a `ViewController`, the next responder is
925+
// the view controller; otherwise, the next responder is the view's
926+
// superview.
927+
928+
// FIXME(compnerd) how do we determine if we are the root view of a view
929+
// controller?
930+
return self.superview
926931
}
927932

928933
// MARK - Trait Environment

Sources/SwiftWin32/Windows and Screens/Window.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,13 @@ public class Window: View {
254254
public class var didResignKeyNotification: NSNotification.Name {
255255
NSNotification.Name(rawValue: "UIWindowDidResignKeyNotification")
256256
}
257+
258+
// MARK - Responder Chain
259+
260+
override public var next: Responder? {
261+
// The window's next responder is the `Application` object.
262+
Application.shared
263+
}
257264
}
258265

259266
extension Window {

0 commit comments

Comments
 (0)