2017-02-24 5 views
2

私はこのように私のUIViewControllerにプログラムで追加のUIView持って追加された後:アニメーションのUIViewそれがプログラム

if let myView = Bundle.main.loadNibNamed("MyView", owner: self, options: nil)?.first as? MyView 
    { 
     self.view.addSubview(myView) 
     myView.translatesAutoresizingMaskIntoConstraints = false 
     //Horizontal orientation 
     self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[view]-10-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":myView])) 
    } 

厥の罰金を、ビューが(で、左右に必要なスペースが付加されています0,0)を表示します。

私が達成したいのは、ビューがビューコントローラの下部から中央にアニメーション化され、後で中央から上にアニメーション化されることです。 が、私はそれから中央にそれをアニメーション化しようとしたすべてのだから、最初の現在の位置です(0,0)

は、だから私がやったことです:

UIView.animate(withDuration: 1.0, 
        animations: 
    { 
     let center = NSLayoutConstraint(item: myView, attribute: .centerY, relatedBy: .equal, toItem: self.view, attribute: .centerY, multiplier: 1, constant: CGFloat(0.0)) 
     self.view.addConstraint(center) 
    }) 

まあビューが中央にあるが、それはアニメ化されていません。それは直接それにジャンプします。

制約の定数を設定してからlayoutIfNeeded()を呼び出す必要があると答えた多くの回答が見つかりましたが、このすべての例ではIBOutletとして以前に設定された制約への参照が使用されています私のビューをプログラムで追加してください。

ビューをアニメーション化するには、下から中央、中央から上に適切にアニメーションできますか?

ありがとうございました!

EDIT 1

オーケー

挨拶は私は少しさらに行くと、私が達成したいかを説明しています。 私のView Controllerで、ユーザーに表示される5秒のタイマーの後に、いくつか質問を表示したい。

私は、下から中央へとスライドし、答えられた後、中央から上にスライドする質問が欲しいです。次に、次の質問が下から中央へ、答えがスライドアウトされるなどです。

だから5秒タイマーの後に私が質問を作成し、それをアニメーション化slideInQuestionという名前のメソッドを呼び出します。

func slideInQuestion() 
{ 
    let question:QuestionView = createQuestion() 
    UIView.animate(withDuration: 1.0, 
        animations: 
    { 
     self.yConstraint?.constant = CGFloat(0.0) 
     self.view.layoutIfNeeded() 
    }) 

createQuestion方法は、質問ビューをインスタンス化し、それ

func createQuestion() -> QuestionView 
{ 
    if let questionView = Bundle.main.loadNibNamed("QuestionView", owner: self, options: nil)?.first as? QuestionView 
    { 
     self.view.addSubview(questionView) 
     questionView.translatesAutoresizingMaskIntoConstraints = false 
     //Horizontal orientation 
     self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[view]-10-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":questionView])) 
     yConstraint = NSLayoutConstraint(item: questionView, 
               attribute: .centerY, 
               relatedBy: .equal, 
               toItem: self.view, 
               attribute: .centerY, 
               multiplier: 1, 
               constant: CGFloat(UIScreen.main.bounds.height)) 
     self.view.addConstraint(yConstraint!) 
     return questionView 
    } 
    return QuestionView() 
} 
に制約を割り当て

以前、私はyConstraintを次のようにDuncan Cによって提案されたインスタンス変数として定義しました:

var yConstraint:NSLayoutConstraint? 

私は今何を期待しているのですか:

質問のビューが作成され、その中心がビューコントローラの中心と画面の高さにあります。これにより、画面の下に表示される視界の外側になります。次に、この位置から画面の中央(0.0)に1秒以内にスライドします。

しかし、それは今、画面のcenterYに画面の上からスライドされず、また、同時に、それは左の余白に変更され、それが第1の制約

に設定されている右のように
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[view]-10-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":questionView])) 

今私は完全に混乱しています。私の説明が助けてくれて、誰かが考えてくれることを願っています。

ありがとうございました!

+0

なぜプログラムとIBOutletの関係が問題なのですか?必要に応じてプレアニメーションの制約を設定し、必要に応じてポストアニメーションの制約を設定し、アニメーションブロック内で変更したいときは 'layoutIfNeeded'を呼び出します。 – Connor

答えて

1

を私はあなたのビューは、あなたのバンドルから作成されたのか分からないので、あなたのコードに基づいた簡単な例をまとめました。

キーはself.view.layoutIfNeeded()が2回呼び出されることです。ビューが追加された後は1回、アニメーションブロックでは2回目です。また、制約の変更はアニメーションブロック内にはありません。

import UIKit 

class ViewController: UIViewController { 

    var yConstraint:NSLayoutConstraint? 

    override func viewWillAppear(_ animated: Bool) { 

     self.createView() 

     self.view.layoutIfNeeded() 

     self.yConstraint?.constant = 32 
     UIView.animate(withDuration: 1.0) { 
      self.view.layoutIfNeeded() 
     } 

    } 

    func createView(){ 

     let questionView = UIView() 
     questionView.backgroundColor = UIColor.red 

     let heightConstraint = NSLayoutConstraint(item: questionView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: self.view.bounds.height-64) 
     questionView.addConstraint(heightConstraint) 

     self.view.addSubview(questionView) 

     questionView.translatesAutoresizingMaskIntoConstraints = false 

     //Horizontal orientation 
     self.view.addConstraints(
      NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[view]-10-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":questionView])) 

     yConstraint = NSLayoutConstraint(item: questionView, 
             attribute: .top, 
             relatedBy: .equal, 
             toItem: self.view, 
             attribute: .top, 
             multiplier: 1, 
             constant: CGFloat(UIScreen.main.bounds.height)) 
     self.view.addConstraint(yConstraint!) 
    } 
} 
+0

ありがとうございました!実際問題は、layoutIfNeededを2回呼び出さなければならないということでした。ビューをコントローラに追加した後、アニメーションブロックに追加する。 今日、何かを学んだ、ありがとう! –

1

制約を作成し、インスタンス変数に保存します。アニメーションを作成する場合は、ストーリーボードベースの制約をアニメートするのと同じように、制約の定数を変更し、アニメーションブロックからlayoutIfNeededを呼び出します。

あなたの場合、機能内にlet constraint = ...を使用しないでください。代わりに、使用:viewWillAppearで

var centerConstraint: NSLayoutConstraint? 

centerConstraint = NSLayoutConstraint(item: myView, 
    attribute: .centerY, 
    relatedBy: .equal, 
    toItem: self.view, 
    attribute: .centerY, 
    multiplier: 1, 
    constant: CGFloat(0.0)) 
self.view.addConstraint(center) 

そして、あなたがアニメーション化したいとき:

UIView.animate(withDuration: 1.0, 
        animations: 
    { 
     centerConstraint.constant = newValue //(Your value here.) 
     myView.layoutIfNeeded() 
    }) 
+0

ありがとう、はい、あなたはそれが昨日遅くになっているはずです。 実際、変数に制約を格納できます。 しかし、私はまだ問題があります。私は複数のコメントを追加する必要がありますが、私は説明するのに十分な文字がありません。申し訳ありません。 –

+0

私は yConstraint = NSLayoutConstraint(アイテムのように私の制約を置く:MYVIEW、 属性:.centerY、 relatedBy:.equal、 toItem:self.view、 属性:.centerY、 乗数:1、 定数:CGFloat( UIScreen.main.bounds.height)) self.view.addConstraint(yConstraint) –

+0

と UIView.animate(withDurationのようにそれを更新します!1.0、 アニメーション:? { self.yConstraint .constant = CGFloat(0.0) self.view.layoutIfNeeded() }) しかし、それはトップからスライドします、なぜですか?そして、それだけではなく、私が設定した最初の制約(左のマージンと右のマージンを維持する最初のポストで見ることができます)から左右の境界のサイズを変更します。 私が長いこと残念に思うほど、私はもっと混乱しています。 self.viewの代わりにmyViewでlayoutIfNeededを呼び出すことは効果がありません。左右のサイズのみが変更されます –

関連する問題