Change USDZ model in ARQuickLook

686 Views Asked by At

I am working on an iOS shopping app that has the AR feature. Users can preview the products in AR using the iOS Quicklook. AR models are the usdz files.

Due to app/design requirements, I had to add custom views on Quicklook screen. Users should be able to select the color in AR Quicklook screen so I've created a new viewcontroller derived from QLPreviewController and added some UI components (collectionview, buttons, etc). I have different models for each color so when the user selects color then App should load a different model (usdz file). Here is the code snippet.

class ARViewController: QLPreviewController {
    override func viewDidLoad() {
        // add UI elements here (collectionview, buttons, ..)
    }
}

Everything is okay till now. I can open the AR Quicklook and can place the object first time.

The problems are

  • when I change the product by selecting the collectionview cell, Quicklook automatically switched to "Object" view even previous model is in AR screen (camera)
  • AR screen (camera) becomes disable state. I can't see new models in AR screen anymore. I have to close the AR screen to reactive the AR mode. or sometimes I have to restart the app (just dismissing the QLPreviewController is not working for next AR view).

Here is the QLPreviewDataSource code

class ViewController: QLPreviewControllerDataSource {
    func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
        return 1 // I did try to update this number but did not worked
    }

    func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
        let productUrl = getProductUrl()
        return productUrl as QLPreviewItem // I did try to pass ARQuickLookPreviewItem but same issue
    }
}

When the user taps on the collectionViewCell in Quiclook, I just updated the AR model name and called QLPreviewController's reloadData function.

self.reloadData() // Also tried self.refreshCurrentPreviewItem() but same issue

Any help would be greatly appreciated. Thanks!

1

There are 1 best solutions below

2
On

Look at this solution to check whether you accordingly implemented QLPreviewController delegate methods. You can use them inside ARViewController's extension for the code published below.

In addition to the above, the following code snippet must be helpful. It's not exactly your case but it works. I used here TableView controller and a separate XIB file called ARObjectTableViewCell.

class ARViewController: UITableViewController {
    
    let models = ["model_01","model_02","model_03"]
    var selectedIndex: Int = 0
        
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let xib = UINib(nibName: "ARObjectTableViewCell", bundle: nil)            
        self.tableView.register(xib, 
                       forCellReuseIdentifier: "objectDetailCell")
    }
    
    override func tableView(_ tableView: UITableView,
          numberOfRowsInSection section: Int) -> Int {
        return self.models.count
    }
    
    override func tableView(_ tableView: UITableView,
                 cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell: ARObjectTableViewCell = tableView.dequeueReusableCell(
                        withIdentifier: "objectDetailCell",
                                   for: indexPath) as! ARObjectTableViewCell
        
        let modelName = models[indexPath.row]
        cell.modelLabel.text = modelName.uppercased()
        
        if let image = UIImage(named: "\(modelName)") {
            cell.modelImageView.image = image
        }
        return cell
    }
    
    override func tableView(_ tableView: UITableView,
         heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 150.0
    }
    
    override func tableView(_ tableView: UITableView,
               didSelectRowAt indexPath: IndexPath) {
        
        tableView.deselectRow(at: indexPath,
                        animated: true)
        
        self.selectedIndex = indexPath.row
        
        let previewController = QLPreviewController()
        previewController.delegate = self
        previewController.dataSource = self
        self.present(previewController, animated: true)
    }
}