两个视图之间的共享祖先

hpi*_*que 5 algorithm uikit uiview ios

找到两个UIView实例之间最低共同祖先的最有效方法是什么?

如果没有实现最低共同祖先,是否有任何UIKitAPI可以用来找到它?

NSViewancestorSharedWithView:让我怀疑这可能是加比晚至iOS越快.

我目前正在使用这种快速而肮脏的解决方案,如果给定的视图不是兄弟或直接的祖先,这是低效的.

- (UIView*)lyt_ancestorSharedWithView:(UIView*)aView
{
    if (aView == nil) return nil;
    if (self == aView) return self;
    if (self == aView.superview) return self;
    UIView *ancestor = [self.superview lyt_ancestorSharedWithView:aView];
    if (ancestor) return ancestor;
    return [self lyt_ancestorSharedWithView:aView.superview];
}
Run Code Online (Sandbox Code Playgroud)

(对于那些实现类似方法的人,Lyt项目的单元测试可能会有所帮助)

Car*_*erg 7

使用-isDescendantOfView:它并不太难.

- (UIView *)my_ancestorSharedWithView:(UIView *)aView
{
    UIView *testView = self;
    while (testView && ![aView isDescendantOfView:testView])
    {
        testView = [testView superview];
    }
    return testView;
}
Run Code Online (Sandbox Code Playgroud)


Or *_*Ron 5

斯威夫特 3:

extension UIView {
    func findCommonSuperWith(_ view:UIView) -> UIView? {

        var a:UIView? = self
        var b:UIView? = view
        var superSet = Set<UIView>()
        while a != nil || b != nil {

            if let aSuper = a {
                if !superSet.contains(aSuper) { superSet.insert(aSuper) }
                else { return aSuper }
            }
            if let bSuper = b {
                if !superSet.contains(bSuper) { superSet.insert(bSuper) }
                else { return bSuper }
            }
            a = a?.superview
            b = b?.superview
        }
        return nil

    }
} 
Run Code Online (Sandbox Code Playgroud)


BB9*_*B9z 1

您的实现仅在一次迭代中检查两个视图级别。

\n\n

这是我的:

\n\n
+ (UIView *)commonSuperviewWith:(UIView *)view1 anotherView:(UIView *)view2 {\n    NSParameterAssert(view1);\n    NSParameterAssert(view2);\n    if (view1 == view2) return view1.superview;\n\n    // They are in diffrent window, so they wont have a common ancestor.\n    if (view1.window != view2.window) return nil;\n\n    // As we don\xe2\x80\x99t know which view has a heigher level in view hierarchy,\n    // We will add these view and their superview to an array.\n    NSMutableArray *mergedViewHierarchy = [@[ view1, view2 ] mutableCopy];\n    UIView *commonSuperview = nil;\n\n    // Loop until all superviews are included in this array or find a view\xe2\x80\x99s superview in this array.\n    NSInteger checkIndex = 0;\n    UIView *checkingView = nil;\n    while (checkIndex < mergedViewHierarchy.count && !commonSuperview) {\n        checkingView = mergedViewHierarchy[checkIndex++];\n\n        UIView *superview = checkingView.superview;\n        if ([mergedViewHierarchy containsObject:superview]) {\n            commonSuperview = superview;\n        }\n        else if (checkingView.superview) {\n            [mergedViewHierarchy addObject:superview];\n        }\n    }\n    return commonSuperview;\n}\n
Run Code Online (Sandbox Code Playgroud)\n