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

Joo*_*. P 20 cocoa-touch uiscrollview uiview ios swift

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

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

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

我试过了

override var frame: CGRect {
    didSet {
        println("frame changed");
    }
}
Run Code Online (Sandbox Code Playgroud)

在UIView子类中,

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

sim*_*ons 35

viewWillLayoutSubviews()并且viewDidLayoutSubviews()只要边界发生变化就会被调用.在视图控制器中.

  • 这是一个`UIView**Controller**`方法,而不是所请求的`UIView`方法。 (23认同)

bea*_*a13 31

这里有一个答案:

/sf/answers/1931364081/

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

override var bounds: CGRect {
    didSet {
        // Do stuff here
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不能保证检测“边界”更改是否有效,这取决于将视图放置在视图层次结构中的位置。我会改写`layoutSubviews`。请参阅[this](/sf/answers/3563130371/)和[this](/sf/answers/350230751/)答案。 (2认同)

Sea*_*rzi 9

您可以创建一个自定义类,并使用闭包轻松获取更新的矩形。在处理类时特别方便(比如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)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

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
}
Run Code Online (Sandbox Code Playgroud)

如果您不通过代码添加视图,则可以将情节提要中的自定义类属性设置为GView

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


Lef*_*ris 5

你也可以使用KVO:

您可以设置一个志愿这个样子,哪里view就是view你要观察帧之间的变化:

self.addObserver(view, forKeyPath: "center", options: NSKeyValueObservingOptions.New, context: nil)
Run Code Online (Sandbox Code Playgroud)

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

override func observeValueForKeyPath(keyPath: String!, ofObject object: AnyObject!, change: NSDictionary!, context: CMutableVoidPointer) {
    }
Run Code Online (Sandbox Code Playgroud)

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

还记得在视图即将被释放时删除观察者:

view.removeObserver(self, forKeyPath:@"center")
Run Code Online (Sandbox Code Playgroud)

  • UIKit上的KVO可能会随时中断.所以应该仅作为最后的手段使用,并准备在未来的iOS版本中失败.请看iOS UIKit工程师的答案:http://stackoverflow.com/a/6051404/251394 (4认同)