无法使用CGRect更改CollectionView框架

时间:2018-09-30 18:07:18

标签: ios swift uicollectionview

我正在尝试使用CollectionView构建一个简单的侧面菜单。问题是我无法使用它,因为使用CGRect更改框架似乎没有任何作用,并且菜单也不会出现。任何帮助将不胜感激。

let blackView = UIView()
var collectionView: UICollectionView {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = UIColor.white
    return cv
}

func showMenu() {
    if let window = UIApplication.shared.keyWindow {

    blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
    blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))



    window.addSubview(blackView)
    window.addSubview(collectionView)

    //This line doesn't work
    collectionView.frame = CGRect(x: 0, y: 0, width: 700, height: window.frame.height)

    //This works fine
    blackView.frame = window.frame

2 个答案:

答案 0 :(得分:0)

那是因为这里的集合视图:

window.addSubview(collectionView)

和收藏在这里查看

//This line doesn't work
collectionView.frame = CGRect(x: 0, y: 0, width: 700, height: window.frame.height)

是不同的对象。您将第一个collectionView添加到窗口,然后更改第二个的框架。误解来自以下代码:

var collectionView: UICollectionView {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = UIColor.white
    return cv
}

这将创建一个动态变量,以便每当您访问collectionView时,都会创建一个新的UICollectionView。它实际上等效于一个函数调用。就像

func makeCollectionView() -> UICollectionView {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = UIColor.white
    return cv
}

然后再做

window.addSubview(makeCollectionView())

//This line doesn't work
makeCollectionView().frame = CGRect(x: 0, y: 0, width: 700, height: window.frame.height)

您应该做的是在开头定义变量,然后再对其进行初始化。例如这样的

let blackView = UIView()
var collectionView: UICollectionView!

func showMenu() {
    if let window = UIApplication.shared.keyWindow {

    blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
    blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))

    // Create collectionView
    if collectionView == nil {
        collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
        collectionView.backgroundColor = UIColor.white
    }

    window.addSubview(blackView)
    window.addSubview(collectionView)

    //This line works finally
    collectionView.frame = CGRect(x: 0, y: 0, width: 700, height: window.frame.height)

    //This works fine
    blackView.frame = window.frame

(取决于您的代码设置,您可能必须在viewDidLoad或类似位置(我不确定)中的另一个位置创建collectionView)

答案 1 :(得分:0)

您将错误的惰性变量定义如下:

var collectionView: UICollectionView {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor.white
return cv
}

在这种情况下,以下是正确的格式,这表示其为READONLY。你回来后不能改变。

var collectionView: UICollectionView {
get{
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor.white
return cv}
}

因此,如果要更改框架,则应在返回之前进行更改,如下所示:

 var collectionView: UICollectionView {
get{
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor.white
cv.frame = CGRect(x: 0, y: 0, width: 300, height: 300) // just an example.
return cv}
}

您真正想要的应该是这样并将其定义为计算属性,然后您可以在任意位置更改帧:

 var collectionView : UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = UIColor.white
    return cv
}()

因此,基本上,您只是想念“ =”和“()”。希望您现在知道原因。