How to detect when UIView size is changed in swift

2020-05-18 11:32发布

I am trying some stuffs out with CATiledLayer inside UIScrollView.

Somehow, the size of UIView inside the UIScrollView gets changed to a large number. I need to find out exactly what is causing this resize.

Is there a way to detect when the size of UIView(either frame, bounds) or the contentSize of UIScrollView is resized?

I tried

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

inside UIView subclass,

but it is only called once when the app starts, although the size of UIView is resized afterwards.

5条回答
Emotional °昔
2楼-- · 2020-05-18 11:47

STEP 1:viewWillLayoutSubviews

Called to notify the view controller that its view is about to layout its subviews

When a view's bounds change, the view adjusts the position of its subviews. Your view controller can override this method to make changes before the view lays out its subviews. The default implementation of this method does nothing.

STEP 2:viewDidLayoutSubviews

Called to notify the view controller that its view has just laid out its subviews.

When the bounds change for a view controller's view, the view adjusts the positions of its subviews and then the system calls this method. However, this method being called does not indicate that the individual layouts of the view's subviews have been adjusted. Each subview is responsible for adjusting its own layout.

Your view controller can override this method to make changes after the view lays out its subviews. The default implementation of this method does nothing.

Above these methods are called whenever bounds of UIView is changed

查看更多
【Aperson】
3楼-- · 2020-05-18 11:59

The answers are correct, although for my case the constraints I setup in storyboard caused the UIView size to change without calling back any detecting functions.

查看更多
何必那么认真
4楼-- · 2020-05-18 12:02

viewWillLayoutSubviews() and viewDidLayoutSubviews() will be called whenever the bounds change. In the view controller.

查看更多
相关推荐>>
5楼-- · 2020-05-18 12:04

There's an answer here:

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

Just paste this outside of a method body:

override var bounds: CGRect {
    didSet {
        // Do stuff here
    }
}
查看更多
够拽才男人
6楼-- · 2020-05-18 12:06

You can also use KVO:

You can set a KVO like this, where view is the view you want to observe frame changes for:

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

And you can get the changes with this notification:

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

The observeValueForKeyPath will be called whenever the frame of the view you are observing changes.

Also remember to remove the observer when your view is about to be deallocated:

view.removeObserver(self, forKeyPath:"center")
查看更多
登录 后发表回答