0

in my iOS swift 3.0 application, I presented UIAlertController sheet instance over my current ViewController. But I don't want to dismiss that sheet when I tapped on outside an area of the sheet (dimmed semi-transparent background) because I already have to cancel an action. Any idea?

I have MGSwipeTableViewCell with more button. When User clicks on that "More" button, following code executes.

func onClickMore(for vmCell: VmCell) {
    let sheet = UIAlertController(title: vmCell.vmItem?.vmNameWithoutIp, message: vmCell.vmItem?.ipAddress, preferredStyle: .actionSheet)

    sheet.addAction(UIAlertAction(title: "Create Ticket", style: .default) { (action: UIAlertAction) in

    })

    sheet.addAction(UIAlertAction(title: "Start VM", style: .default) { (action: UIAlertAction) in

    })

    sheet.addAction(UIAlertAction(title: "Restart VM", style: .default) { (action: UIAlertAction) in

    })

    sheet.addAction(UIAlertAction(title: "Stop VM", style: .destructive) { (action: UIAlertAction) in

    })

    sheet.addAction(UIAlertAction(title: "Cancel", style: .cancel) { (action: UIAlertAction) in

    })

    present(sheet, animated: true) { 
        sheet.view.superview?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: nil))
    }
}
appleBoy21
  • 632
  • 8
  • 23
  • see this link: http://stackoverflow.com/questions/8632944/any-way-to-prevent-uiactionsheet-from-being-dismissed-when-user-clicks-a-button – Aashish1aug Apr 04 '17 at 06:05
  • http://stackoverflow.com/questions/25466718/uialertcontroller-handle-dismiss-upon-click-outside-ipad – Harish Pathak Apr 04 '17 at 06:05

1 Answers1

5

for UIAlertController Type as alert

you can download the sample project

add the gesture recognizer to alertController superview for handle the userinteraction

self.present(alertController, animated: true, completion: {() -> Void in
 alertController.view.superview?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: nil)
})

on that action do nothing

update

let alertController = UIAlertController(title: "Do something", message: "With this", preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "Done", style: .default) { action in
        // perhaps use action.title here
    })

    self.present(alertController, animated: true, completion: {() -> Void in


        alertController.view.superview?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: nil))
    })

for UIAlertController Type as actionSheet

you can download the sample project

you can do this two ways

option 1

 alert.view.superview.subviews[0] isUserInteractionEnabled = false

option 2

   alert.view.superview?.subviews[0].addGestureRecognizer(UITapGestureRecognizer(target: self, action: nil))

for e.g

   self.present(sheet, animated: true, completion: {() -> Void in
    //    sheet.view.superview?.subviews[0].isUserInteractionEnabled = false;
      sheet.view.superview?.subviews[0].addGestureRecognizer(UITapGestureRecognizer(target: self, action: nil))

    })

full code

  let sheet = UIAlertController(title: "karthik", message: "check with", preferredStyle: .actionSheet)

    sheet.addAction(UIAlertAction(title: "Create Ticket", style: .default) { (action: UIAlertAction) in

    })

    sheet.addAction(UIAlertAction(title: "Start VM", style: .default) { (action: UIAlertAction) in

    })

    sheet.addAction(UIAlertAction(title: "Restart VM", style: .default) { (action: UIAlertAction) in

    })

    sheet.addAction(UIAlertAction(title: "Stop VM", style: .destructive) { (action: UIAlertAction) in

    })

    sheet.addAction(UIAlertAction(title: "Cancel", style: .cancel) { (action: UIAlertAction) in

    })



    self.present(sheet, animated: true, completion: {() -> Void in
    //    sheet.view.superview?.subviews[0].isUserInteractionEnabled = false;
      sheet.view.superview?.subviews[0].addGestureRecognizer(UITapGestureRecognizer(target: self, action: nil))

    })
Anbu.Karthik
  • 82,064
  • 23
  • 174
  • 143
  • @Sanket - can you update the question, its working perfectly in my side,wait i will attach the sample project – Anbu.Karthik Apr 04 '17 at 06:17
  • @Sanket - check the sample project – Anbu.Karthik Apr 04 '17 at 06:20
  • i think when you set preferred style = .alertSheet, then it will not wrk – appleBoy21 Apr 04 '17 at 06:24
  • may i know the downvote reason , check the update answer, – Anbu.Karthik Apr 04 '17 at 06:41
  • @Anbu.Karthik: This will not work when you set the style to actionSheet. In your example you are setting that property to alert. – Midhun MP Apr 04 '17 at 06:41
  • @MidhunMP - its works perfectly , I added the sample projects for both ***actionsheet*** and ***alert*** also, verify once – Anbu.Karthik Apr 04 '17 at 06:45
  • @Anbu.Karthik: It seems like a hack than a solution, it can break in future releases if apple changes it's action sheet view hierarchy. However in current situation it yields the result and I'm retracting my down-vote. – Midhun MP Apr 04 '17 at 06:52
  • 2
    @MidhunMP - its ok my bro, but UIalertcontroller, there is no public API, for direct handle this, we need to take the view hiearchy , but in future apple changes the hierachy, definitly I will update my answer – Anbu.Karthik Apr 04 '17 at 06:54
  • 2
    @Anbu.Karthik: There are several other ways, but not perfect ways. 1) If it is in iPad you can use the popover presentation controller delegate to disable the dismissal. 2) In iPhone if you don't specify the action style to cancel it won't dismiss the action sheet when clicking outside, you can set the style to default in that case. – Midhun MP Apr 04 '17 at 06:58
  • @MidhunMP - one more question, now you are react the downvote to upvote ,but its not increase the 10 marks in my account how its possible but it only update +2 marks – Anbu.Karthik Apr 04 '17 at 07:00
  • 1
    Thanks to both of you. @MidhunMP: Your discussion helps me a lot in understanding the concept. – appleBoy21 Apr 04 '17 at 07:10
  • @Anbu.Karthik: Your solution now working Correctly. Thanks again – appleBoy21 Apr 04 '17 at 07:10