SvenTiigi / WhatsNewKit

Showcase your awesome new app features 📱
https://sventiigi.github.io/WhatsNewKit/
MIT License
3.92k stars 193 forks source link

Don't animate itemsView. #20

Closed mjkoo711 closed 5 years ago

mjkoo711 commented 5 years ago

Hi, I'm MJ.

First, thank you for your open source.

I'm using your open source WhatsNewKit. But, I met a problem.

I want to animate views, but itemsview does not apply animation.

Below my code. Thank you.

import Foundation
import WhatsNewKit

class WhatsNewAppHandler {
  var whatsNewViewController: WhatsNewViewController?

  init() {
    let whatsNew = WhatsNew(
      title: "WhatsNewKit",
      items: [
        WhatsNew.Item(
          title: "Installation",
          subtitle: "You can install WhatsNewKit via CocoaPods or Carthage",
          image: UIImage(named: "IAPAds")
        ),
        WhatsNew.Item(
          title: "Open Source",
          subtitle: "Contributions are very welcome 👨‍💻",
          image: UIImage(named: "IAPAds")
        ),
        WhatsNew.Item(
          title: "Installation",
          subtitle: "You can install WhatsNewKit via CocoaPods or Carthage",
          image: UIImage(named: "IAPAds")
        ),
        WhatsNew.Item(
          title: "Installation",
          subtitle: "You can install WhatsNewKit via CocoaPods or Carthage",
          image: UIImage(named: "IAPAds")
        )
      ]
    )

    var configuration = WhatsNewViewController.Configuration()
    configuration.completionButton.backgroundColor = Color.Blue
    configuration.apply(animation: .slideUp)

    whatsNewViewController = WhatsNewViewController(
      whatsNew: whatsNew,
      configuration: configuration
    )
  }

  func showsWhatsNewApp(presentViewController: UIViewController) {

    if let whatsNewViewController = self.whatsNewViewController {
      whatsNewViewController.modalTransitionStyle = .coverVertical
      whatsNewViewController.modalPresentationStyle = .overFullScreen
      presentViewController.present(whatsNewViewController, animated: true)
    }
  }
}
SvenTiigi commented 5 years ago

Hey @mjkoo711,

Thanks for your detailed bug report 🙌

Internally the ItemView will perform its animation as soon as the willDisplayCell function from the UITableViewDelegate has been invoked.

To give you further assistance it might be important to have a look at the caller-side for the func showsWhatsNewApp in which context the presentation is happening (through a press of the button, while a transition, etc..).

Additionally it is important to know if only the ItemsView is not animating but the rest like the TitleView or CompletionButton is performing its animation.

Maybe you could also try this code-snippet and test if the ItemsView perform the animation.

func showsWhatsNewApp(presentViewController: UIViewController) {
        DispatchQueue.main.async {
            if let whatsNewViewController = self.whatsNewViewController {
                whatsNewViewController.modalTransitionStyle = .coverVertical
                whatsNewViewController.modalPresentationStyle = .overFullScreen
                presentViewController.present(whatsNewViewController, animated: true)
            }
        }
 }
mjkoo711 commented 5 years ago

@SvenTiigi Thank you for your answer, but It still has a same problems. ㅠㅠ Furthermore, the TitleView only animate without itemsView, buttonView

SvenTiigi commented 5 years ago

I've tried your code in an example app with the latest version of WhatsNewKit (1.1.8) which invokes the showsWhatsNewApp function on a button press and all animations are as expected.

So it would be interesting where or how you invoking your showsWhatsNewApp function in your code.

Demo

mjkoo711 commented 5 years ago

image

@SvenTiigi I called the viewWillAppear in MainViewController, which is first View Controller in my app.

mjkoo711 commented 5 years ago

@SvenTiigi I wanted to launch the whatsNewViewController when app was opened.

mjkoo711 commented 5 years ago

@SvenTiigi Xcode ver.10.2.1, version >= iOS 11

mjkoo711 commented 5 years ago

@SvenTiigi I think the problem related with MainViewController's collectionView present timing. Hum,,, or viewDidLoad, viewWillAppear, viewDidAppear method should not invoke the showsWhatsNewApp.

SvenTiigi commented 5 years ago

You might wanna check out your console output in Xcode there must be something like this:

Presenting view controllers on detached view controllers is discouraged

Because you are presenting the WhatsNewViewController before your UIViewController has finished loading the view.

But I've identified a bug which I'm currently fixing. The animation of the ItemsView is disabled as soon as an orientationDidChange notification has been posted to avoid re-animating. And when presenting the WhatsNewViewController during a View-Lifecycle where the view is not loaded like viewWillAppear that notification will be posted by iOS and therefore the animation is disabled.

I will release a new Version 1.1.9 which fixes this bug and your reported bug. But please consider presenting or pushing a ViewController during a View-Lifecycle is not recommended.

mjkoo711 commented 5 years ago

@SvenTiigi Oh, thank you. I have a question. This SDK is StartKitfeature and I want to show immediately when users come in app. So, where is the optimize place calling shows the showsWhatsNewViewController method? Or HOW CAN I PRESENT THE ViewController?

mjkoo711 commented 5 years ago

Although my English is not good, I'm happy for your help.

SvenTiigi commented 5 years ago

Version 1.1.9 should allow you presenting the WhatsNewViewController during viewWillAppear with all animations working correctly.

To get rid of this warning:

Presenting view controllers on detached view controllers is discouraged

You can either delay the presentation on the Main Thread.

override func viewWillAppear(_ animated: Bool) {
     super.viewWillAppear(animated)
     DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
          WhatsNewAppHandler().showsWhatsNewApp(presentViewController: self)            
     }
}

Or you use the UIWindow rootViewController in the viewDidAppear lifecycle.

override func viewDidAppear(_ animated: Bool) {
     super.viewDidAppear(animated)
     WhatsNewAppHandler().showsWhatsNewApp(
          presentViewController: self.view.window?.rootViewController
     )
}

Read more: https://stackoverflow.com/a/21003988

mjkoo711 commented 5 years ago

@SvenTiigi Thank you. Have a good day.