首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用KVO观测contentSize (CGSize)

用KVO观测contentSize (CGSize)
EN

Stack Overflow用户
提问于 2015-07-15 04:14:05
回答 4查看 15.3K关注 0票数 10

我试图像这样观察collectionView.contentSize

代码语言:javascript
运行
复制
func startObserveCollectionView() {
    collectionView.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.Old.union(NSKeyValueObservingOptions.New), context: &SearchDasboardLabelContext)
}

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    if context == &SearchDasboardLabelContext {       
        if object === collectionView && keyPath! == "contentSize" {
            print(change)               
        }
    }
}

在xcode终端中,我得到了一个NSSize而不是CGSize,如下所示:

代码语言:javascript
运行
复制
Optional(["old": NSSize: {320, 0}, "new": NSSize: {375, 39.5}, "kind": 1])

在目标-c中,我使用了CGSizeValue方法

代码语言:javascript
运行
复制
CGSize newContentSize = [[change objectForKey:NSKeyValueChangeNewKey] CGSizeValue];

在斯威夫特有类似CGSizeValue的方法吗?

我试过使用var newContentSize = change[NSKeyValueChangeNewKey]?.CGSizeValue(),但是出错了

找不到“CGSizeValue”成员

需要帮忙吗?谢谢

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-08-26 22:32:24

你上iOS了吗?因为我是,我做了同样的事情,得出了同样的问题:为什么是NSSize?也许那只是xcode终端在捉弄我们。

无论如何,您可以将其转换为NSValue,然后就可以使用CGSizeValue了。

代码语言:javascript
运行
复制
if let zeChange = change as? [NSString: NSValue] {
    let oldSize = zeChange[NSKeyValueChangeOldKey]?.CGSizeValue()
    let newSize = zeChange[NSKeyValueChangeNewKey]?.CGSizeValue()
}
票数 3
EN

Stack Overflow用户

发布于 2017-08-10 20:21:57

使用Swift 4,您可以将change字典的结果转换为NSKeyValueChangeKey.newKey类型的CGSize

代码语言:javascript
运行
复制
if let size = change?[NSKeyValueChangeKey.newKey] as? CGSize {
    /* ... */
}

下面的UIViewController实现演示了如何设置KVO堆栈,以便观察任何UIScrollView子类(例如UITextView)的contentSize属性的变化:

代码语言:javascript
运行
复制
import UIKit

private var myContext = 0

class ViewController: UIViewController {

    @IBOutlet weak var textView: UITextView!

    /* ... */

    override func viewDidLoad() {
        super.viewDidLoad()

        textView.addObserver(self, forKeyPath: #keyPath(UITextView.contentSize), options: [NSKeyValueObservingOptions.new], context: &myContext)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if context == &myContext,
            keyPath == #keyPath(UITextView.contentSize),
            let contentSize = change?[NSKeyValueChangeKey.newKey] as? CGSize {
            print("contentSize:", contentSize)
        }
    }

    deinit {
        textView.removeObserver(self, forKeyPath: #keyPath(UITextView.contentSize))
    }

}

请注意,使用Swift 4作为addObserver(_:, forKeyPath:, options:, context:)observeValue(forKeyPath:, of:, change:, context:)的替代方法,您可以使用observe(_:, options:, changeHandler:)来跟踪UIScrollView子类contentSize属性的更改:

代码语言:javascript
运行
复制
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var textView: UITextView!
    var observer: NSKeyValueObservation?

    /* ... */

    override func viewDidLoad() {
        super.viewDidLoad()

        let handler = { (textView: UITextView, change: NSKeyValueObservedChange<CGSize>) in
            if let contentSize = change.newValue {
                print("contentSize:", contentSize)
            }
        }
        observer = textView.observe(\UITextView.contentSize, options: [NSKeyValueObservingOptions.new], changeHandler: handler)
    }

}
票数 14
EN

Stack Overflow用户

发布于 2019-04-26 10:08:24

还有一种更简单、更快捷的选择。

您可以子类UICollectionViewLayout (或它的任何子类,如UICollectionViewFlowLayout)并覆盖计算的属性collectionViewContentSize。通过调用super,您将获得集合的contentSize,并能够将此值委托给您的代码。

所以你会得到这样的东西:

代码语言:javascript
运行
复制
protocol FlowLayoutDelegate: class {
    func collectionView(_ collectionView: UICollectionView?, didChange contentSize: CGSize)
}

class FlowLayout: UICollectionViewFlowLayout {

    weak var delegate: FlowLayoutDelegate?

    override var collectionViewContentSize: CGSize {
        let contentSize = super.collectionViewContentSize
        delegate?.collectionView(collectionView, didChange: contentSize)
        return contentSize
    }

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31421387

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档