我正在使用UIScrollView中的CATiledLayer尝试一些东西。
不知何故,UIScrollView中UIView的大小变为大数。我需要找出导致此调整大小的确切原因。
有没有办法检测UIView的大小(帧,边界)或UIScrollView的contentSize何时调整大小?
我试过
override var frame: CGRect {
didSet {
println("frame changed");
}
}
在UIView子类中,
但只在应用程序启动时调用一次,但之后会调整UIView的大小。
答案 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()
}