0

I have a tap gesture action which opens a Apple App Store product display:

    let storeProductViewController = SKStoreProductViewController()

    @objc func adTap(sender: UITapGestureRecognizer? = nil) -> Void {
        if  adAppID.isEmpty {return}
        let paramDict = [SKStoreProductParameterITunesItemIdentifier: adAppID]
        storeProductViewController.loadProduct(withParameters: paramDict, completionBlock: { (status: Bool, error: Error?) -> Void in
            if status {
//                self.storeProductViewController.edgesForExtendedLayout = []
//              self.storeProductViewController.additionalSafeAreaInsets = UIEdgeInsets(top: 40, left: 0, bottom: 0, right: 0)
//                self.storeProductViewController.modalPresentationCapturesStatusBarAppearance = false
                self.present(self.storeProductViewController, animated: true, completion: nil)
            }
            else {
                if let error = error {
                    print("Error: \(error.localizedDescription)")
                }
            }})
    }

    func productViewControllerDidFinish(_ viewController: SKStoreProductViewController) {
        viewController.presentingViewController?.dismiss(animated: true, completion: nil)
    }

First time user taps, all well and good. Tap the standard, system-provided "Done" button and the modal Store view is popped and the user is returned to the original view in the app.

If the user taps the gestured-action view again, the Store product view is displayed, but the Done button shifted up, and is now underneath the time display above the "Safe" area. It is partly obscured by the time, and is also insensitive to a tap. Deadlock - no way to return to my App.

I did not explicitly create the Nav Controller that SKStore uses and I don't think I can get control of it.

I have tried the three approaches commented out in the code to push the presented Store view and its accessory done button down. none of the three worked.

What am I doing wrong here, or how can it be fixed?

Addendum: More failed approaches: After instantiation of the store view, I tried directly setting its view and layer frames, and I also inset the safe area and margins of the parent view - all no effect on Done button.

Further down the Rabbit hole: Comparing screenshots of the first and second calls to the StoreProductView Present (Note, two different products, but that does not matter, I tried them all!), we can see that the vertical offset to the store App Icon and Name are the same for both views. It is only the "Done" button that has moved from it's normal place to up under the time/location in use area.

try 1 Trial 1

try 2 Trial 2

BlueskyMed
  • 765
  • 7
  • 24
  • It could be how you creating navigation stack. Check out this post https://stackoverflow.com/questions/17074365/status-bar-and-navigation-bar-appear-over-my-views-bounds-in-ios-7 – k-thorat May 09 '19 at 00:42
  • Thanks for the fast reply! As I said in the OP, I just have a standard one view app, and I did not create a Nav or embed in a Nav Stack. I believe the SKStoreProductController does that for itself. Also, as noted above I tried ExtendedEdges, additionalSafeAreaInsets, and also ModalPresentationCapturesStatusBar, etc. I still haven't found a solution – BlueskyMed May 09 '19 at 03:28
  • Could you please put sample project on github? – k-thorat May 09 '19 at 03:40
  • The `productViewControllerDidFinish` method gives you the VC that is being presented doesn't it? doesn't just calling dismiss on that work? – Scriptable May 09 '19 at 08:03
  • Hi Scriptable! Yes it does, but in this case the presented VC is the Store kit Product page and the only UI a user has to dismiss it seems to be the "Done" button it provides. Tapping Done is what triggers the DidFinish method. The problem here is that the StoreVC, on the second time it presents is shifted up and under the System NavBar/Notch on a real device iPhoneXsMax/ iOS 12.2 – BlueskyMed May 09 '19 at 16:44

1 Answers1

0

Further investigation revealed that the StoreProductViewController had a view.frame.origin.y that was changing (for reasons unknown, I wasn't changing it knowingly):

Native rects, first run (No forced changes)
Self.View.frame: (0.0, 0.0, 414.0, 896.0)
Self.View.bounds: (0.0, 0.0, 414.0, 896.0)
Store.View.frame: (0.0, 0.0, 0.0, 0.0)
Store.View.bounds: (0.0, 0.0, 0.0, 0.0)

Native rects, second run
Self.View.frame: (0.0, 0.0, 414.0, 896.0)
Self.View.bounds: (0.0, 0.0, 414.0, 896.0)
Store.View.frame: (0.0, 896.0, 414.0, 896.0)
Store.View.bounds: (0.0, 0.0, 414.0, 896.0)

So, i just forced it to revert to the original value by placing this line just before the presentVC

self.self.storeProductViewController.frame.origin.y = 0.0

then the button stays where it belongs and the debugging traces are:

Force store origin.y to zero  first run
Self.View.frame: (0.0, 0.0, 414.0, 896.0)
Self.View.bounds: (0.0, 0.0, 414.0, 896.0)
Store.View.frame: (0.0, 0.0, 0.0, 0.0)
Store.View.bounds: (0.0, 0.0, 0.0, 0.0)

Force store origin.y to zero, second run
Self.View.frame: (0.0, 0.0, 414.0, 896.0)
Self.View.bounds: (0.0, 0.0, 414.0, 896.0)
Store.View.frame: (0.0, 0.0, 414.0, 896.0)
Store.View.bounds: (0.0, 0.0, 414.0, 896.0)
BlueskyMed
  • 765
  • 7
  • 24