hpi*_*que 5 algorithm uikit uiview ios
找到两个UIView实例之间最低共同祖先的最有效方法是什么?
如果没有实现最低共同祖先,是否有任何UIKitAPI可以用来找到它?
NSView有ancestorSharedWithView:让我怀疑这可能是加比晚至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项目的单元测试可能会有所帮助)
使用-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)
斯威夫特 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)
您的实现仅在一次迭代中检查两个视图级别。
\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}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2651 次 |
| 最近记录: |