2017-01-31 8 views
1

私はswiftのFBSDKLoginButtonでアニメーションイベントを呼び出そうとしています。アルファ値を変更している要素が正しく機能するため、アニメーションが呼び出されていることがわかります。ただし何らかの理由で、同じ呼び出しでボタンは移動しません。完了イベントからの迅速なアニメーションの呼び出し?

別のボタンをタッチして、まったく同じ機能を呼び出すと、ボタンが移動します。完了イベントから別の場所を呼び出す理由が、オブジェクトが実際に移動するかどうかに影響するかどうかはわかりません。

BTN_Animateの下では、コールが動作する場所です。

LocalProfile.sharedInstance.updateFromFacebook(updateFromFacebook_Complete: 

コールすると同じ関数が表示され、引き継がれる引数はtrueとみなされます。

@IBAction func BTN_Animate(_ sender: Any) { 

    animateScreen(loggedIn: true) //Call that works 
} 

public func loginButton(_ BTN_facebookLogin: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) { 
    print("> Attempting Login from Main View Controller") 

    if ((error) != nil) 
    { 
     print("Error: ") 
     // Process error 
     print(error) 
    } 
    else if result.isCancelled { 
     // Handle cancellations 
     print("Request cancelled") 
     print(result) 
    } 
    else { 
     // If you ask for multiple permissions at once, you 
     // should check if specific permissions missing 


     LocalProfile.sharedInstance.updateFromFacebook(updateFromFacebook_Complete: { 

      self.LBL_Name.text = LocalProfile.sharedInstance.firstName 

      self.IMG_ProfilePicture.image = LocalProfile.sharedInstance.profilePicture 

      LocalProfile.sharedInstance.printAllData() 

      self.animateScreen(loggedIn: LocalProfile.sharedInstance.loggedIn) //Call that doesn't work 

     }) 




    } 

} 

public func animateScreen(loggedIn: Bool) { 

    if(loggedIn) { 

     //Animating screen objects 
     print("> Animating screen objects") 

     UIView.animate(withDuration: 0.7, delay: 1.0, options: UIViewAnimationOptions.curveEaseOut, animations: { 
      self.BTN_facebookLogin.frame = CGRect(x: self.BTN_facebookLogin.frame.origin.x, y: (self.view.bounds.height - self.BTN_facebookLogin.frame.size.height) - 50, width: self.BTN_facebookLogin.frame.size.width, height: self.BTN_facebookLogin.frame.size.height) 

      self.IMG_ProfilePicture.alpha = 1 
      self.LBL_Name.alpha = 1 

      self.view.layoutIfNeeded() 
     }, completion: { finished in 
      print("> Done animating screen objects") 
     }) 



    } 
    else { 

     //Not animating 
     print("> Not animating screen objects") 

    } 


} 

ここにご協力ください!おかげ

EDITは: メインキューであなたのボタンのフレームを更新するようにしてください:コードの下には、周りのメインスレッド...

LocalProfile.sharedInstance.updateFromFacebook(updateFromFacebook_Complete: { 

      self.LBL_Name.text = LocalProfile.sharedInstance.firstName 

      self.IMG_ProfilePicture.image = LocalProfile.sharedInstance.profilePicture 

      LocalProfile.sharedInstance.printAllData() 

      self.animateScreen(loggedIn: LocalProfile.sharedInstance.loggedIn) 

      let notString = Thread.isMainThread ? "" : "not " 
      print("This is " + notString + "the main thread") 

     }) 
+2

ヒント - 常にメインキューのUI更新を行います。 – rmaddy

答えて

1

作品であることを返します。スウィフト3.0では次のようにすることができます。

DispatchQueue.main.async 
{ 
    self.BTN_facebookLogin.frame = CGRect(x: self.BTN_facebookLogin.frame.origin.x, y: (self.view.bounds.height - self.BTN_facebookLogin.frame.size.height) - 50, width: self.BTN_facebookLogin.frame.size.width, height: self.BTN_facebookLogin.frame.size.height) 
    self.IMG_ProfilePicture.alpha = 1 
    self.LBL_Name.alpha = 1 
    self.view.layoutIfNeeded() 
} 
+0

completionHandlerからアニメーション化したいものの周りに 'DispatchQueue.main.async {}'を追加すると、問題が修正されました。ありがとう! –

1

他の人からも言われているように、メインスレッドからUIコールを行う必要があります。 FacebookのAPIに精通していないので、使用している補完ブロックがメインスレッドで呼び出されているかどうかわかりません。

let notString = Thread.isMainThread ? "" : "not " 
print("This is " + notString + "the main thread") 

を(それはスウィフト3のコードです)

あなたの完了ブロックの上部にあることを入れて、それがコンソールに表示されるか見て:あなたはこのようなコードで確認することができます。

私の考えは、完了ブロックがメインスレッドで実行されていないということです。

バックグラウンドスレッドからUI呼び出しを実行する最も一般的な効果は、何も起こらないか、または有効にするのに非常に時間がかかります。しかし、それはまた、他の奇妙な効果やクラッシュさえも引き起こす可能性があるので、それをしないことが重要です。

フレームレイアウトを妨げる自動レイアウトに問題があるかもしれませんが、記述した現象(完了ブロックからは動作しませんが、直接呼び出すと動作します)に基づいて、スレッドの問題のように聞こえるようになります。

完了ブロックを処理するときは、完了ブロックがバックグラウンドスレッドから呼び出されるかどうかを判断する必要があります。 AppleのURLSessionクラスは、バックグラウンドスレッドでコンプリートブロックを呼び出すクラスの例です。完成ブロックがバックグラウンドスレッドで呼び出されたかどうかを教えてください。しかし、上に投稿したテストコードは確かに良い方法です。これに対して、UIViewanimateWithDuarion(animations:completion:)ファミリのメソッド群は、メインスレッド上で完了ブロックを呼び出します。

+0

返信いただきありがとうございます!しかしちょうど情報のために、私はあなたが言ったようにして、それがメインスレッドであることを得ました。下のコード編集:コメントの書式設定が嫌なので編集として追加されました –

関連する問題