Use previousSibling() instead of nextSibling() for overlay injection
This commit is contained in:
parent
31aaf169e1
commit
4afd79ffc4
|
@ -20,10 +20,34 @@ public enum Introspect {
|
|||
return nil
|
||||
}
|
||||
|
||||
/// Finds a sibling that contains a view of the specified type.
|
||||
/// Finds the next sibling that contains a view of the specified type.
|
||||
/// This method inspects siblings recursively.
|
||||
/// Returns nil if no sibling contains the specified type.
|
||||
public static func firstSibling<AnyViewType: UIView>(
|
||||
public static func previousSibling<AnyViewType: UIView>(
|
||||
containing type: AnyViewType.Type,
|
||||
from entry: UIView
|
||||
) -> AnyViewType? {
|
||||
|
||||
guard let superview = entry.superview,
|
||||
let entryIndex = superview.subviews.firstIndex(of: entry),
|
||||
entryIndex > 0
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
for subview in superview.subviews[0..<entryIndex].reversed() {
|
||||
if let typed = findChild(ofType: type, in: subview) {
|
||||
return typed
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Finds the next sibling that contains a view of the specified type.
|
||||
/// This method inspects siblings recursively.
|
||||
/// Returns nil if no sibling contains the specified type.
|
||||
public static func nextSibling<AnyViewType: UIView>(
|
||||
containing type: AnyViewType.Type,
|
||||
from entry: UIView
|
||||
) -> AnyViewType? {
|
||||
|
@ -225,7 +249,7 @@ extension View {
|
|||
}
|
||||
|
||||
// Search in siblings
|
||||
return Introspect.firstSibling(containing: UITableView.self, from: viewHost)
|
||||
return Introspect.previousSibling(containing: UITableView.self, from: viewHost)
|
||||
},
|
||||
customize: customize
|
||||
))
|
||||
|
@ -246,7 +270,7 @@ extension View {
|
|||
}
|
||||
|
||||
// Search in siblings
|
||||
return Introspect.firstSibling(containing: UIScrollView.self, from: viewHost)
|
||||
return Introspect.previousSibling(containing: UIScrollView.self, from: viewHost)
|
||||
},
|
||||
customize: customize
|
||||
))
|
||||
|
@ -275,7 +299,7 @@ extension View {
|
|||
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
|
||||
return nil
|
||||
}
|
||||
return Introspect.firstSibling(containing: UITextField.self, from: viewHost)
|
||||
return Introspect.previousSibling(containing: UITextField.self, from: viewHost)
|
||||
},
|
||||
customize: customize
|
||||
))
|
||||
|
@ -288,7 +312,7 @@ extension View {
|
|||
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
|
||||
return nil
|
||||
}
|
||||
return Introspect.firstSibling(containing: UISwitch.self, from: viewHost)
|
||||
return Introspect.previousSibling(containing: UISwitch.self, from: viewHost)
|
||||
},
|
||||
customize: customize
|
||||
))
|
||||
|
@ -301,7 +325,7 @@ extension View {
|
|||
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
|
||||
return nil
|
||||
}
|
||||
return Introspect.firstSibling(containing: UISlider.self, from: viewHost)
|
||||
return Introspect.previousSibling(containing: UISlider.self, from: viewHost)
|
||||
},
|
||||
customize: customize
|
||||
))
|
||||
|
@ -314,7 +338,7 @@ extension View {
|
|||
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
|
||||
return nil
|
||||
}
|
||||
return Introspect.firstSibling(containing: UIStepper.self, from: viewHost)
|
||||
return Introspect.previousSibling(containing: UIStepper.self, from: viewHost)
|
||||
},
|
||||
customize: customize
|
||||
))
|
||||
|
@ -327,7 +351,7 @@ extension View {
|
|||
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
|
||||
return nil
|
||||
}
|
||||
return Introspect.firstSibling(containing: UIDatePicker.self, from: viewHost)
|
||||
return Introspect.previousSibling(containing: UIDatePicker.self, from: viewHost)
|
||||
},
|
||||
customize: customize
|
||||
))
|
||||
|
|
12
README.md
12
README.md
|
@ -14,15 +14,14 @@ Introspect works by adding a custom `IntrospectionView` to the view hierarchy, t
|
|||
|
||||
For instance, when introspecting a `TextField`, it will:
|
||||
|
||||
- Add `IntrospectionView` as the background of `TextField`
|
||||
- Add `IntrospectionView` as an overlay of `TextField`
|
||||
- Get the view host of the introspection view (which is alongside the view host of the `UITextField`)
|
||||
- Get the next sibling containing `UITextField`
|
||||
- Get the previous sibling containing `UITextField`
|
||||
|
||||
**Please note that this introspection method might break in future SwiftUI releases.** Future implementations might not use the same hierarchy, or might not use UIKit elements that are being looked for. Though the library is unlikely to crash, the `.introspect()` method will not be called in those cases.
|
||||
|
||||
### Usage in production
|
||||
|
||||
|
||||
`Introspect` is meant to be used in production. It does not use any private API. It only inspects the view hierarchy using publicly available methods. The library takes a defensive approach to inspecting the view hierarchy: there is no hard assumption that elements are laid out a certain way, there is no force-cast to UIKit classes, and the `introspect()` methods are simply ignored if UIKit views cannot be found.
|
||||
|
||||
|
||||
|
@ -130,7 +129,7 @@ extension View {
|
|||
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
|
||||
return nil
|
||||
}
|
||||
return Introspect.firstSibling(containing: UITextField.self, from: viewHost)
|
||||
return Introspect.previousSibling(containing: UITextField.self, from: viewHost)
|
||||
},
|
||||
customize: customize
|
||||
))
|
||||
|
@ -141,7 +140,8 @@ extension View {
|
|||
You can use any of the following [methods](https://github.com/timbersoftware/SwiftUI-Introspect/blob/master/Introspect/Introspect.swift#L3-L71) to inspect the hierarchy:
|
||||
|
||||
- `Introspect.findChild(ofType:in:)`
|
||||
- `Introspect.firstSibling(containing:from:)`
|
||||
- `Introspect.previousSibling(containing:from:)`
|
||||
- `Introspect.nextSibling(containing:from:)`
|
||||
- `Introspect.findAncestor(ofType:from:)`
|
||||
- `Introspect.findHostingView(from:)`
|
||||
- `Introspect.findViewHost(from:)`
|
||||
- `Introspect.findViewHost(from:)`
|
||||
|
|
Loading…
Reference in New Issue