Fail to make drag and drop feature as accessible

Hello Team,
 
We have accessibilityDragSourceDescriptions and accessibilityDropSourceDescriptions, how can we connect these point of location with custom actions to make the drag and drop feature to be accessible by VoiceOver and Voice Control. If anyone has sample code for accessible of drag and drop, that will be very helpful for me. Thank you

I'd recommend checking out this WWDC video, it should cover everything you need to do. You shouldn't need to manually expose custom actions, rather VoiceOver should find your drag and drop descriptors automatically and add that action for users:
https://developer.apple.com/videos/play/wwdc2018/241/
Hi,

Thank you for the response. Yes, i understand it no need to add any custom actions, based on accessibilityDragSourceDescriptors property its adding the actions.

Got one more challenge as how we can add Drag featues for more than 1 object for session.
This UIDragInteractionDelegate is assign to single object only at a time. In my application we have multiple objects in a view, for all those objects need to add UIDragInteraction,help me how to achieve this.

Without accessibility, if we add UIDragInteraction for ViewObject(contains our over all drag objects) it's working fine.
With Accessibility, for which uiobject we add UIDragInteractionDelegate only for that particular object voice over adding the custom actions.

CodeSample - Without Accessibility
Code Block
override func viewDidLoad() {
    super.viewDidLoad()
let dragInt = UIDragInteraction.init(delegate: self)
    dragInt.isEnabled = true
    dragView.addInteraction(dragInt) //added Drag interaction
dragView.addInteraction(UIDropInteraction.init(delegate: self)) //added Drop interaction
}
func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
     
    let touchpoint = session.location(in: self.dragView)
    if let touimgview = self.view.hitTest(touchpoint, with: nil) as? UIImageView {
       
      let touchedimage = touimgview.image
       
      let itemProvider = NSItemProvider(object: touchedimage!)
      let dragItem = UIDragItem(itemProvider: itemProvider)
      dragItem.localObject = touimgview
      return [dragItem]
    }
     
    return []
  }
   
  func dragInteraction(_ interaction: UIDragInteraction, previewForLifting item: UIDragItem, session: UIDragSession) -> UITargetedDragPreview? {
    return UITargetedDragPreview(view: item.localObject as! UIView)
  }
 func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
    for dragItem in session.items {
      dragItem.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: { (obj, err) in
         
        if let err = err {
          print("Failed to load our dragged item:", err)
          return
        }
         
         
        guard let draggedImage = obj as? UIImage else { return }
         
         
         
        DispatchQueue.main.async {
          let dragItemis = dragItem.localObject as! UIImageView
        let touchpoint = session.location(in: self.dragView)
  if self.dropimgeViewObject.frame.contains(touchpoint) {
          self.dropimgeViewObject.image = draggedImage
        }
}
})
    }
  }
 func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
    return UIDropProposal(operation: .copy)
  }
   
  func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
    return session.canLoadObjects(ofClass: UIImage.self)
  }
   

Above code is working fine.

Code Sample - With Accessibility
Code Block  
 @IBOutlet weak var img1 : UIImageView!
  @IBOutlet weak var img2 : UIImageView!
  @IBOutlet weak var img3 : UIImageView!
  @IBOutlet weak var viweofDrag : UIView!
 override func viewDidLoad() {
    super.viewDidLoad()
    let dragInteloc2 = UIAccessibilityLocationDescriptor(name: "Drag Object", point: img1.center, in: self.img1)
       self.img1.accessibilityDragSourceDescriptors = [dragInteloc2]
    self.img1.accessibilityLabel = "Drag Circle"
 let dragInteloc3 = UIAccessibilityLocationDescriptor(name: "Drag Object", point: img2.center, in: self.img2)
       self.img2.accessibilityDragSourceDescriptors = [dragInteloc3]
    self.img2.accessibilityLabel = "Drag Circle"
     
    let dragint = UIDragInteraction(delegate: self)
    dragint.isEnabled = true
    self.img1.addInteraction(dragint) //only img1 viewobject only have action items for Voice over
     self.img2.addInteraction(dragint) //how to achieve this, not working
    let dropinte = UIDropInteraction(delegate: self)
    self.img2.addInteraction(dropinte)
     
    let dropinte2 = UIDropInteraction(delegate: self)
    self.img3.addInteraction(dropinte2)     
  }
func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
     
    guard let image = img1.image else {
      return []
    }
    let irem = UIDragItem(itemProvider: NSItemProvider(object: image))
    irem.localObject = image
    return [irem]
  }
   
  func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
    return true
  }
   
  func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
    let droploc = session.location(in: self.viweofDrag)
    let operat : UIDropOperation
    if img2.frame.contains(droploc) || img3.frame.contains(droploc) {
      operat = session.localDragSession == nil ? .copy : .move
    }
    else{
      operat = .cancel
    }
    return UIDropProposal(operation: operat)
  }
   
  func dropInteraction(_ interaction: UIDropInteraction, sessionDidEnd session: UIDropSession) {
    let droploc = session.location(in: self.viweofDrag)
    self.updateLayes(droploc: droploc)
  }
   
  func dropInteraction(_ interaction: UIDropInteraction, sessionDidExit session: UIDropSession) {
    let droploc = session.location(in: self.viweofDrag)
    self.updateLayes(droploc: droploc)
  }
   
  func updateLayes(droploc : CGPoint) {
    if img2.frame.contains(droploc) {
      img2.image = UIImage.init(named: "1")
      img1.image = UIImage.init(named: "2")
      self.img1.accessibilityLabel = "Drag Square"
    }
    else if img3.frame.contains(droploc){
      img3.image = UIImage.init(named: "2")
      img1.image = nil
    }
     
  }


Help me to solve this issue.

Thank you


Fail to make drag and drop feature as accessible
 
 
Q