使用约束在 UITableViewController 中添加 UIActivityIndi​​catorView 时出错。无法使用 SnapKit 使用锚激活约束

Posted

技术标签:

【中文标题】使用约束在 UITableViewController 中添加 UIActivityIndi​​catorView 时出错。无法使用 SnapKit 使用锚激活约束【英文标题】:Error adding UIActivityIndicatorView in UITableViewController using constraints. Unable to activate constraint with anchors using SnapKit 【发布时间】:2017-11-25 02:18:30 【问题描述】:

当我在 UITableViewController 内部设置 UIActivityIndi​​catorView 的约束时,我的应用程序中出现此错误。调用 showFooter 函数时出现错误:

致命异常:NSGenericException 无法使用锚激活约束,因为它们没有共同的祖先。约束或其锚点是否引用不同视图层次结构中的项目?这是违法的。

func showFooter(show: Bool) 
    DispatchQueue.main.safeAsync 
        if show 
            let loadingFooter = UIActivityIndicatorView(activityIndicatorStyle: .gray)
            UIApplication.shared.keyWindow?.addSubview(loadingFooter)
            loadingFooter.startAnimating()
            loadingFooter.snp.makeConstraints  make in
                make.centerX.equalTo(self.view.snp.centerX)
                make.height.equalTo(20)
                make.bottom.equalTo(self.view.snp.bottom).inset(49)
            
         else 
            UIApplication.shared.keyWindow?.subviews.forEach  ($0 as? UIActivityIndicatorView)?.removeFromSuperview() 
        
    


public struct ConstraintViewDSL: ConstraintAttributesDSL  
    public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) 
        ConstraintMaker.makeConstraints(item: self.view, closure: closure)
    


public extension ConstraintView 
    public var snp: ConstraintViewDSL 
        return ConstraintViewDSL(view: self)
    

回溯/调试日志:

Fatal Exception: NSGenericException
0  CoreFoundation                 0x182609d04 __exceptionPreprocess
1  libobjc.A.dylib                0x181858528 objc_exception_throw
2  CoreFoundation                 0x182609c4c -[NSException initWithCoder:]
3  Foundation                     0x183118d18 -[NSLayoutConstraint _setActive:mutuallyExclusiveConstraints:]
4  Foundation                     0x183119004 __55+[NSLayoutConstraint _addOrRemoveConstraints:activate:]_block_invoke
5  Foundation                     0x182f3b59c -[NSISEngine withBehaviors:performModifications:]
6  Foundation                     0x183118ed4 +[NSLayoutConstraint _addOrRemoveConstraints:activate:]
7  SnapKit                        0x10281b54c specialized static ConstraintMaker.makeConstraints(item : LayoutConstraintItem, closure : (ConstraintMaker) -> ()) -> () (ConstraintMaker.swift:272)
8  SnapKit                        0x10281e578 ConstraintViewDSL.makeConstraints((ConstraintMaker) -> ()) -> () (ConstraintViewDSL.swift)
9  Zattini                        0x101341fc0 specialized UIViewController.(showFooter(show : Bool) -> ()).(closure #1) (UIViewController+Extensions.swift:140)
10 Zattini                        0x101340dd8 UIViewController.showFooter(show : Bool) -> () (UIViewController+Extensions.swift:14)
11 Zattini                        0x101340f10 @objc UIViewController.showFooter(show : Bool) -> () (UIViewController+Extensions.swift)
12 Zattini                        0x10132f5c4 ProductListControllerZattiniProductListDelegate (ProductListController.swift:197)
13 Zattini                        0x1013881cc ProductListViewModel.loadMoreProducts() -> () (ProductListViewModel.swift:159)
14 Zattini                        0x101331858 specialized ProductListController.scrollViewDidScroll(UIScrollView) -> () (ProductListController.swift:192)
15 Zattini                        0x10132de80 @objc ProductListController.scrollViewDidScroll(UIScrollView) -> () (ProductListController.swift)
16 UIKit                          0x18bd4270c -[UIScrollView(UIScrollViewInternal) _notifyDidScroll]
17 UIKit                          0x18ba5f090 -[UIScrollView setContentOffset:]
18 UIKit                          0x18bd46398 -[UIScrollView(UIScrollViewInternal) _adjustContentOffsetIfNecessary]
19 UIKit                          0x18ba99cc4 -[UIScrollView setBounds:]
20 UIKit                          0x18ba99580 -[UICollectionView setBounds:]
21 UIKit                          0x18bd1dcf4 -[UIView(Geometry) _applyISEngineLayoutValuesToBoundsOnly:]
22 UIKit                          0x18ba585c8 -[UIView(Geometry) _resizeWithOldSuperviewSize:]
23 UIKit                          0x18c5e4b48 -[UIScrollView(_UIOldConstraintBasedLayoutSupport) _resizeWithOldSuperviewSize:]
24 CoreFoundation                 0x1824e3a6c -[__NSArrayM enumerateObjectsWithOptions:usingBlock:]
25 UIKit                          0x18ba46af8 -[UIView(Geometry) resizeSubviewsWithOldSize:]
26 UIKit                          0x18bb2f018 -[UIView(AdditionalLayoutSupport) _is_layout]
27 UIKit                          0x18bd21228 -[UIView(Hierarchy) _updateConstraintsAsNecessaryAndApplyLayoutFromEngine]
28 UIKit                          0x18ba3e304 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
29 QuartzCore                     0x1865f7ec8 -[CALayer layoutSublayers]
30 QuartzCore                     0x1865fbfa8 CA::Layer::layout_if_needed(CA::Transaction*)
31 UIKit                          0x18ba530a8 -[UIView(Hierarchy) layoutBelowIfNeeded]
32 UIKit                          0x18bae8d7c -[UINavigationController _layoutViewController:]
33 UIKit                          0x18bae644c -[UINavigationController _layoutTopViewController]
34 UIKit                          0x18bdcf3c8 __105-[UINavigationController _repositionPaletteWithNavigationBarHidden:duration:shouldUpdateNavigationItems:]_block_invoke
35 UIKit                          0x18bdcf0a8 -[UINavigationController _repositionPaletteWithNavigationBarHidden:duration:shouldUpdateNavigationItems:]
36 UIKit                          0x18bae5a78 -[UINavigationController _updateBarsForCurrentInterfaceOrientation]
37 UIKit                          0x18bb67cac -[UITabBarController _updateLayoutForStatusBarAndInterfaceOrientation]
38 CoreFoundation                 0x18259c0bc __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__
39 CoreFoundation                 0x18259b65c _CFXRegistrationPost
40 CoreFoundation                 0x18259b3c0 ___CFXNotificationPost_block_invoke
41 CoreFoundation                 0x1826189c4 -[_CFXNotificationRegistrar find:object:observer:enumerator:]
42 CoreFoundation                 0x1824d20c0 _CFXNotificationPost
43 Foundation                     0x182ef3498 -[NSNotificationCenter postNotificationName:object:userInfo:]
44 UIKit                          0x18bf3f10c -[__UICanvasLifecycleMonitor_Compatability activateEventsOnly:withContext:completion:]
45 UIKit                          0x18c6ba4b8 __82-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]_block_invoke
46 UIKit                          0x18c6ba35c -[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]
47 UIKit                          0x18c42c294 __125-    [_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]_block_invoke
48 UIKit                          0x18c5c30ac _performActionsWithDelayForTransitionContext
49 UIKit                          0x18c42c144 -[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]
50 UIKit                          0x18c2122d8 -[_UICanvas scene:didUpdateWithDiff:transitionContext:completion:]
51 UIKit                          0x18c0b4d68 -[UIApplicationSceneClientAgent scene:handleEvent:withCompletion:]
52 FrontBoardServices             0x184cb620c __80-[FBSSceneImpl updater:didUpdateSettings:withDiff:transitionContext:completion:]_block_invoke.362
53 libdispatch.dylib              0x181f8d048 _dispatch_client_callout
54 libdispatch.dylib              0x181f946c8 _dispatch_block_invoke_direct$VARIANT$mp
55 FrontBoardServices             0x184ce99f4 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__
56 FrontBoardServices             0x184ce9698 -[FBSSerialQueue _performNext]
57 FrontBoardServices             0x184ce9c34 -[FBSSerialQueue _performNextFromRunLoopSource]
58 CoreFoundation                 0x1825b22e8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
59 CoreFoundation                 0x1825b2268 __CFRunLoopDoSource0
60 CoreFoundation                 0x1825b1af0 __CFRunLoopDoSources0
61 CoreFoundation                 0x1825af6c8 __CFRunLoopRun
62 CoreFoundation                 0x1824cffb8 CFRunLoopRunSpecific
63 GraphicsServices               0x184367f84 GSEventRunModal
64 UIKit                          0x18baa42f4 UIApplicationMain
65 Zattini                        0x101113a84 main (AppDelegate.swift:21)
66 libdyld.dylib                  0x181ff256c start

【问题讨论】:

【参考方案1】:

您只能在同一视图层次结构中的UIViews 之间设置约束。您将UIActivityIndicatorView 直接添加到应用程序的关键窗口,然后尝试为视图控制器的视图设置约束。这两个 UIView 不在同一个视图层次结构中,所以你会得到一个错误。

这是UIActivityIndicatorView的视图层次结构:

这是视图控制器view的视图层次结构:

要使其工作,您必须在 UIActivityIndicatorViewkeyWindow 之间设置约束:

func showFooter(show: Bool) 
    guard let keyWindow = UIApplication.shared.keyWindow else  return 
    if show 
        let loadingFooter = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        loadingFooter.backgroundColor = .red
        keyWindow.addSubview(loadingFooter)
        loadingFooter.startAnimating()
        loadingFooter.snp.makeConstraints  make in
            make.centerX.equalTo(keyWindow)
            make.height.equalTo(20)
            make.bottom.equalTo(keyWindow).inset(49)
        
     else 
        UIApplication.shared.keyWindow?.subviews.forEach  ($0 as? UIActivityIndicatorView)?.removeFromSuperview() 
    

另一件小事。当您在 2 个视图的相同锚点而不是

之间设置约束时
make.centerX.equalTo(self.view.snp.centerX)

你可以写

make.centerX.equalTo(self.view)

有点短;-)

【讨论】:

我使用了类似的方法来解决这个问题并且崩溃停止了!

以上是关于使用约束在 UITableViewController 中添加 UIActivityIndi​​catorView 时出错。无法使用 SnapKit 使用锚激活约束的主要内容,如果未能解决你的问题,请参考以下文章

tableHeaderView中的UITextView找不到委托

viewController的生命周期

将 UITableView 实例化为弹出框时,UITableViewCell 的属性为零

使用约束

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

使用约束在 UITableViewController 中添加 UIActivityIndi​​catorView 时出错。无法使用 SnapKit 使用锚激活约束