7

UICollectionViewユーザーが何らかのアクションを行うとき、下から特定の高さまで引き上げる必要があります。その新しい状態は完全にオプションであるため、コレクション ビューはそのように表示される直前に作成されます。下から上へのアニメーションは、NSLayoutConstraint のconstantプロパティへの変更と[view layoutIfNeeded]いくつかのアニメーション ブロックでの呼び出しを使用して実行されます。

問題は、そのようにすると、セルが望ましくない方法で表示されることです。セルは左上隅から指定されたサイズに拡大します。コレクション ビューが表示され、そのすべてのセルが最終的なサイズと外観でレイアウトされていることを望みます。

私は UIView のsetAnimationEnabled:メソッドのようなものを認識していますが、それをどこでどのように使用すべきかを見つけることができないようです (それが正しい方法である場合)。

への呼び出しを含むアニメーション ブロックの直前にコレクション ビュー セルがビュー階層に追加されていることが原因だと思います[superview layoutIfNeeded]。これにより、おそらく UIKit は、レイアウトへのこれらの変更もアニメーション化する必要があると考えるようになります。その場合、解決策はおそらくアニメーションから除外する方法に沿ったものであり、ビュー階層への特定の変更です。

4

2 に答える 2

15

左上隅からの拡張は、通常layoutIfNeeded、元のビューが一度もレイアウトされていないときにアニメーション ブロックを呼び出した場合の兆候です。基本的に、すべてのサブビューが CGRectZero で開始されている初期レイアウト パスをアニメーション化しています。

それを解決するには、次の 2 つのことが必要です。

  • 編集している制約が、サイズではなく、コレクション ビューの位置に関連していることを確認してください。これは、高さをゼロから最終値に変更してコレクション ビューを表示していないことを意味します。
  • 制約を編集する前にビューを呼び出しlayoutIfNeeded、変更を行った後にアニメーション ブロックで再度呼び出します。このようにして、レイアウト全体ではなく、制約に指定した変更のみをアニメーション化します。
于 2013-06-26T21:28:54.877 に答える
0

私はこの問題に約3日間悩まされ、最終的に解決策を得ました。非常に小さなタイマーの後に呼び出されるアニメーションブロックを追加しただけです

UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 7 , options: .CurveEaseInOut, animations: {
            self.view.layoutIfNeeded()
        }){ _ in}

になります

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
    dispatch_after(delayTime, dispatch_get_main_queue()) {
        self.changeConstraint()
    }

private func changeConstraint(){

        UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 7 , options: .CurveEaseInOut, animations: {
            self.view.layoutIfNeeded()
        }){ _ in}
}

魔法を見てください:)

于 2016-09-05T09:09:04.323 に答える