2017-03-19 32 views
2

我想要使用自動佈局(在SnapKit的幫助下)有一個簡單的從頂部向下滑動的動畫。layoutIfNeeded後不立即顯示視圖

下面是我用來生成視圖,設置其約束並強制重新加載(因此顯示)所述視圖的代碼。在相同的代碼中,我將頂部約束更改爲不同的值,並在動畫塊中調用layoutIfNeeded

然而,發生什麼事情是,視圖顯示在預期的位置,沒有任何動畫。

這裏是稱爲的方法中的短延遲(用於其它目的)之後的代碼:

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), execute: { 
    self.view.addSubview(view) 
    view.backgroundColor = .black 

    view.snp.makeConstraints { (make) -> Void in 
     make.left.right.equalToSuperview() 
     make.height.equalTo(200) 
     make.bottom.equalTo(self.view.snp.top) // Pin view to top to prepare slide-down animation 
    } 

    view.setNeedsLayout() 
    view.layoutIfNeeded() 

    view.snp.updateConstraints { (make) -> Void in 
     make.bottom.equalTo(self.view.snp.top).offset(200) 
    } 

    view.setNeedsLayout() 

    UIView.animate(withDuration: 5, animations: { 
     view.layoutIfNeeded() 
    }) 
}) 
+0

我看到幾個潛在的原因。 (1)它看起來像你試圖在一個單獨的線程中做UI更新。我很驚訝它甚至在工作。如果你用這種方式編碼,這是一個主要的禁忌。 (2)爲什麼你要調用* setNeedsLayout()*和* layoutIfNeeded()* ** ** UIView.animate *之外?這是一個可能的罪魁禍首。 (3)約束變化。也許這是與SnapKit相關的東西,但調用* updateContraints()*並不是我在嘗試更改然後動畫約束時所做的。我改變它們中的常量/乘數。 – dfd

+0

(1)之後沒有想過。謝謝。任何提示如何在延遲UI更新後調用方法? 「Sleep()」顯然也是一種不好的方式,因爲它是阻塞的。 (2)我需要在創建動畫之前設置視圖。 (3)SnapKit的UpdateConstraint就是這麼做的。我比較你是否有一個給定的約束,只是更新常數/乘數。 –

+0

@dfd'DispatchQueue.main'確實使用'主線程',所以不用擔心(來源:https://www.hackingwithswift.com/read/9/4/back-to-the-main-thread- dispatchqueuemain)。 –

回答

1

由於In Swift, how do I animate a UIView with auto-layout like a page sliding in?我發現的罪魁禍首。

雖然我不是100%理解這是爲什麼,但layoutIfNeeded需要從superview中調用,而不是視圖本身。

所以調用self.view.layoutIfNeeded()是正確的方法。請注意,目前正在添加viewUIView,而self.view是超級視圖,其中view正在添加到。

+0

在引用兩個不同對象的這些名稱的代碼的同一部分中使用'self.view'和'view'聽起來非常混亂。答案之後,所有事情都開始了嗎?如果是這樣,你可以接受你的答案,所以你得到積分。 :) –

+0

是的,命名不是很聰明:-)它確實解決了這個問題。儘管只能在2天內接受我自己的答案。 –

+1

啊,好的。恭喜你弄明白了! –