如何修复视图居中之谜?

时间:2015-10-25 12:41:49

标签: ios swift cocoa uiimageview uistackview

我有一个UIStackView,它包含一个图像视图和一个文本视图。图像视图将活动指示器视图作为子视图(我以编程方式添加)。当视图最初查看加载时,我将活动指示器视图置于图像视图中并启动AIV的动画。但是,在等待图像加载的过程中,如果我旋转图像视图,则需要重新定位AIV。我添加了代码来监听状态栏方向更改通知,并有一个方法来调用通知(UIApplicationDidChangeStatusBarOrientationNotification)。在该方法中,我尝试获取图像视图的边界,并使用它在图像视图中重新定位AIV。但是,当设备方向改变时,图像视图的边界值似乎不会改变。有可靠的"设备方向更改后获取视图更新边界的方法?代码 - >

// start listening for orientation changes
NSNotificationCenter.defaultCenter().addObserver(self, selector: "orientationDidChange:",
           name: UIApplicationDidChangeStatusBarOrientationNotification, object: nil)

然后我有:

func orientationDidChange(notification: NSNotification) {

   // get image view bounds
   let viewBounds = _imageView.bounds

   // recenter the activity indicator
   _activityIndicator.center = CGPointMake(CGRectGetMidX(viewBounds), CGRectGetMidY(viewBounds))
}

更新

所以我摆脱了上述并尝试了这个:

// setup activity indicator
_activityIndicatorView.translatesAutoresizingMaskIntoConstraints = true

        _imageView.addSubview(_activityIndicatorView)

        // set constraints
        let centerXConstraint = NSLayoutConstraint(item: _activityIndicatorView, attribute: .CenterX,
            relatedBy: .Equal, toItem: _imageView,
            attribute: .CenterX, multiplier: 1.0,
            constant: 0.0)
        _activityIndicatorView.addConstraint(centerXConstraint)

        let centerYConstraint = NSLayoutConstraint(item: _activityIndicatorView, attribute: .CenterY,
            relatedBy: .Equal, toItem: _imageView,
            attribute: .CenterY, multiplier: 1.0,
            constant: 0.0)
        _activityIndicatorView.addConstraint(centerYConstraint)

在我看来是加载方法。控制台吐出这个:

2015-10-27 19:26:09.303 Historic Sites Navigator [373:93902]视图层次结构不是为约束准备的:     添加到视图时,约束的项必须是该视图的后代(或视图本身)。如果在组装视图层次结构之前需要解析约束,则会崩溃。打破 - [UIView(UIConstraintBasedLayout)_viewHierarchyUnpreparedForConstraint:]进行调试。 2015-10-27 19:26:09.308 Historic Sites Navigator [373:93902]查看层次结构未准备好约束。     约束:     容器层次: >    | >     在容器层次结构中找不到视图:>     该视图的超级视图:> 2015-10-27 19:26:09.310历史站点导航器[373:93902] *由于未捕获的异常终止应用程序' NSGenericException',原因:'无法在视图上安装约束。约束是否引用了视图子树之外的内容?这是非法的。约束:查看:>' * 第一次抛出调用堆栈: (0x2643767b 0x377b2e17 0x264375c1 0x27177983 0x2a628f85 0x2a628dd5 0x2a628cef 0x2ad33971 0x2a628bd7 0xdf6c4 0xdfe34 0x2a5271c7 0x2a526dad 0x2ad8ca09 0x2a8689ad 0x2a88c095 0x2a88e6c5 0x2a88e931 0x2a61e98​​9 0x2a891bb7 0x2ab33085 0x2ac09b39 0x2ac09967 0x2a883d95 0xccac8 0xccc10 0x2a659487 0x2a71440b 0x2a7cc0b9 0x2a7d79eb 0x2a519ecd 0x263fa4c9 0x263f87cd 0x263f8bff 0x2634c119 0x2634bf05 0x2f502ac9 0x2a58ef15 0xd6e74 0x37f21873) libc ++ abi.dylib:以NSException类型的未捕获异常终止

2 个答案:

答案 0 :(得分:0)

对于iOS 8和9,在视图大小更改时调用以下函数(例如在界面旋转时):

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    coordinator.animateAlongsideTransition({ (coordinator) -> Void in
        // here the new size is already set, so place your code here
    }, completion: nil)
}

除此之外,你可以使用约束(自动布局)来定位UIActivityIndi​​catorView。

您当前的自动布局错误是因为您必须:

  • 将translatesAutoresizingMaskIntoConstraints设置为false
  • 将约束添加到图像视图,而不是添加到ai-view

答案 1 :(得分:0)

在观看WWDC 2015的Autolayout视频后,我能够编写正确且有效的代码:

NSFastLED::CRGB leds[1];

@ 13:48这个视频是关键: https://developer.apple.com/videos/play/wwdc2015-219/