如何检测swift ios xcode中何时更改UIView大小?

时间:2015-06-03 09:43:15

标签: ios swift cocoa-touch uiview uiscrollview

我正在使用UIScrollView中的CATiledLayer尝试一些东西。

不知何故,UIScrollView中UIView的大小变为大数。我需要找出导致此调整大小的确切原因。

  

有没有办法检测UIView的大小(帧,边界)或UIScrollView的contentSize何时调整大小?

我试过

override var frame: CGRect {
    didSet {
        println("frame changed");
    }
}

在UIView子类中,

但只在应用程序启动时调用一次,但之后会调整UIView的大小。

7 个答案:

答案 0 :(得分:34)

只要边界发生变化,就会调用

viewWillLayoutSubviews()viewDidLayoutSubviews()。在视图控制器中。

答案 1 :(得分:23)

这里有一个答案:

https://stackoverflow.com/a/27590915/5160929

只需将其粘贴到方法体外:

override var bounds: CGRect {
    didSet {
        // Do stuff here
    }
}

答案 2 :(得分:5)

您也可以使用KVO:

您可以像这样设置KVO ,其中view是您要观察帧更改的view

self.addObserver(view, forKeyPath: "center", options: NSKeyValueObservingOptions.New, context: nil)

您可以通过此通知获取更改:

override func observeValueForKeyPath(keyPath: String!, ofObject object: AnyObject!, change: NSDictionary!, context: CMutableVoidPointer) {
    }

只要您观察的视图的帧发生更改,就会调用observeValueForKeyPath

还要记得在视图即将解除分配时删除观察者:

view.removeObserver(self, forKeyPath:@"center")

答案 3 :(得分:2)

答案是正确的,虽然对于我的情况,我在故事板中设置的约束导致UIView大小改变而不回调任何检测功能。

答案 4 :(得分:1)

第1步:viewWillLayoutSubviews

  

调用以通知视图控制器其视图即将发布   布局其子视图

     

当视图的边界发生变化时,视图会调整其位置   子视图。您的视图控制器可以覆盖此方法   视图之前的更改将显示其子视图。默认   这个方法的实现什么都不做。

第2步:viewDidLayoutSubviews

  

调用以通知视图控制器其视图刚刚布局   它的子视图。

     

当视图控制器视图的边界发生变化时,视图   调整其子视图的位置,然后系统调用它   方法。但是,调用此方法并不表示该方法   已调整视图子视图的各个布局。每   subview负责调整自己的布局。

     

您的视图控制器可以覆盖此方法以进行更改   该视图列出了其子视图。这个的默认实现   方法什么都不做。

只要 UIView 的边界发生变化

,就会调用上述方法

答案 5 :(得分:1)

您可以创建一个自定义类,并使用闭包来舒适地获取更新的矩形。在处理类时特别方便(比如 left join,它希望你给它们一个 CAGradientLayer):

CGRect

GView.swift

示例用法:

import Foundation
import UIKit

class GView: UIView {

    var onFrameUpdated: ((_ bounds: CGRect) -> Void)?

    override func layoutSublayers(of layer: CALayer) {
      super.layoutSublayers(of: layer)
      self.onFrameUpdated?(self.bounds)
    }
}

如果您不是通过代码添加视图,您可以将故事板中的自定义类属性设置为 let headerView = GView() let gradientLayer = CAGradientLayer() headerView.layer.insertSublayer(gradientLayer, at: 0) gradientLayer.colors = [ UIColor.mainColorDark.cgColor, UIColor.mainColor.cgColor, ] gradientLayer.locations = [ 0.0, 1.0, ] gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0) gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0) headerView.onFrameUpdated = { _ in // here you have access to `bounds` and `frame` with proper values gradientLayer.frame = headerView.bounds }

请注意,名称 GView 是作为公司衡量标准选择的,可能选择 GView 之类的名称会更好。

答案 6 :(得分:0)

对于 UIViews,就像:

    override func layoutSubviews() {
        super.layoutSubviews()

        setupYourNewLayoutHereMate()
    }