Swift3: Crash on presenting pop over - ios

let obj = MainStoryboard().instantiateViewController(withIdentifier: "SomeVC") as! SomeVC
obj.delegate = self
obj.modalPresentationStyle = .popover
obj.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
self.present(obj, animated: true, completion: nil)
On setting up breakpoints, debugger goes good till last line. After that, it directly goes to AppDelegate class first line.
I have set exception break point properly. Where I might be making a mistake? Is it related to sourceView for popoverPresentationController? I am not sure.
What I want to do is set up the popoverPresentationController in center. Any help?
EDIT:
I added the sourceView to the code like following & now it's working:
obj.popoverPresentationController?.sourceView = self.view
obj.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 1, height: 1)
However, it's not in the center of the screen. Putting screen shot for reference. How do I make it to the center and remove the direction arrow?

After doing the following code changes I was able to make it work.
let obj = MainStoryboard().instantiateViewController(withIdentifier: "SomeVC") as! SomeVC
obj.delegate = self
obj.modalPresentationStyle = .popover
obj.popoverPresentationController?.permittedArrowDirections = .init(rawValue: 0)
obj.popoverPresentationController?.sourceView = self.view
obj.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 1, height: 1)
self.present(obj, animated: true, completion: nil)
Thank You all for your efforts.

You have to use sourceView in conjunction with sourceRect to provide anchor point for pop over, like following:
obj.popoverPresentationController?.sourceView = self.view
obj.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 1, height: 1)
Also, If you don't want the anchor point arrow to be there, then use:
obj.popoverPresentationController?.permittedArrowDirections = .init(rawValue: 0)
It will make your pop over appear in center with no arrow/anchor point.

Try this:
let obj = MainStoryboard().instantiateViewController(withIdentifier: "SomeVC") as! SomeVC
obj.delegate = self
obj.modalPresentationStyle = .overCurrentContext
self.navigationController?.present(obj, animated: false, completion: {
})

Related

Dismiss Activity View Controller above view

How can I dismiss an UIActivityViewController by tapping above the view.
// Setting url
let secondActivityItem : NSURL = NSURL(string: url)!
let activityViewController : UIActivityViewController = UIActivityViewController(
activityItems: [secondActivityItem], applicationActivities: nil)
if(UIDevice.current.userInterfaceIdiom == .pad){
// This lines is for the popover you need to show in iPad
activityViewController.isModalInPresentation = false
activityViewController.popoverPresentationController?.sourceView = self.view//(self as! UIButton)
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 0, height: 0)
}else{
// This lines is for the popover you need to show in iPad
activityViewController.isModalInPresentation = true
activityViewController.popoverPresentationController?.sourceView = (self as! UIButton)
// This line remove the arrow of the popover to show in iPad
activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.down
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 0, height: 0)
}
// Pre-configuring activity items
activityViewController.activityItemsConfiguration = [
UIActivity.ActivityType.message
] as? UIActivityItemsConfigurationReading
// Anything you want to exclude
activityViewController.excludedActivityTypes = [
UIActivity.ActivityType.postToWeibo,
UIActivity.ActivityType.print,
UIActivity.ActivityType.assignToContact,
UIActivity.ActivityType.saveToCameraRoll,
UIActivity.ActivityType.addToReadingList,
UIActivity.ActivityType.postToFlickr,
UIActivity.ActivityType.postToVimeo,
UIActivity.ActivityType.postToTencentWeibo,
UIActivity.ActivityType.postToFacebook,
UIActivity.ActivityType.postToTwitter
]
self.present(activityViewController, animated: true, completion: nil)
I am trying to replicate self.dismiss when the red box area is tapped above the UIActivityViewController (as shown in the image)
After setting isModalInPresentation to true, controller removes support for out-of-area tap gestures.
Solution: don't set isModalInPresentation to true.

Activity View Controller not showing the entire popup

I am trying to make a drawing app and I want to add the activity view controller. It works on the iPhone, but it will not show the entire view controller on the iPad. I have tried many different approaches based off what I have read, but the result is the same. Any help is appreciate.
Code:
#IBAction func actionsTapped(_ sender: Any) {
// Setting description
let message = "Actions for your drawing"
// Get the image to save
let image = getImage()
let activityViewController : UIActivityViewController = UIActivityViewController(activityItems: [message, image], applicationActivities: nil)
// Ipad popup
activityViewController.popoverPresentationController?.sourceView = (self.view)
// Remove Ipad arrow
activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.down
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 0, height: 0)
// Pre-configuring activity items
activityViewController.activityItemsConfiguration = [
UIActivity.ActivityType.message,
UIActivity.ActivityType.print,
UIActivity.ActivityType.saveToCameraRoll,
UIActivity.ActivityType.airDrop
] as? UIActivityItemsConfigurationReading
// Exclude
activityViewController.excludedActivityTypes = [
UIActivity.ActivityType.postToWeibo,
UIActivity.ActivityType.addToReadingList,
UIActivity.ActivityType.postToFlickr,
UIActivity.ActivityType.postToVimeo,
UIActivity.ActivityType.postToTencentWeibo,
UIActivity.ActivityType.postToFacebook
]
activityViewController.isModalInPresentation = true
self.present(activityViewController, animated: true, completion: nil)
}
As someone pointed out, which I tried changing the height and width in the sourceRect does not work. See below where I changed
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 0, height: 0)
to
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 500, height: 500)
My initial thought was that x and y would change the position of the popup and height and width change the size, but it seems that it's the reverse in sourceRect.
It sounds like you're misunderstanding what the sourceRect is. It has nothing to do, in and of itself, with the size of the activity view controller. It determines where the arrow points to.
The activity view controller always has its own full size. I suspect that what's going wrong here is due to this line:
activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.down
That forces the whole activity view controller to appear above the source rect (i.e. more toward the top of the screen) — but there isn't room. If you just cut that line, the activity view controller may be able to appear where there is room.

Getting a sourceRect for UIActivityViewController from a UIDocumentBrowserViewController

I am trying to add a custom activity to my UIDocumentBrowserController long-tap menu - a UIActivityViewController. The default share activity, when selected, is pointing nicely to the icon of the file that the user just long-tapped.
How can I get the sourceRect so that my activity could be presented in a similar way?
let shareBundle = UIDocumentBrowserAction(identifier:
"com.mycompany.myapp.shareBundle", localizedTitle: "Share with Data",
availability: [.menu], handler: { urls in
if urls.count > 0 {
let objectsToShare: [URL] = [urls]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.popoverPresentationController?.sourceView = self.view
activityVC.popoverPresentationController?.sourceRect = // That's the problem!
self.present(activityVC, animated: true, completion: nil)
}
})
Looks like it is currently not possible to get the view of the selected document.
For now I ended up just positioning the ActivityView at the center of the screen and disabling the arrows:
if let popOverController = activityVC.popoverPresentationController {
popOverController.sourceView = self.view
popOverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popOverController.permittedArrowDirections = []
}

Is it possible to pass a gesture from the current view controller to popover viewcontroller

In my presented ViewController i have a button where on the long press I present a ViewController with modalPresentationStyle popover. The thing is I would like to pass the same touch gesture to the popover so that I don't have to make another touch event to make things work. Is it possible in my current situation or do u suggest work around?
interactionViewController?.delegate = self
interactionViewController?.indexpathRow = indexPathRow
interactionViewController?.modalPresentationStyle = .popover
interactionViewController?.popoverPresentationController?.backgroundColor = .clear
interactionViewController?.preferredContentSize = CGSize(width: 320, height: 220)
interactionViewController?.view.layer.cornerRadius = 25
let popoverMenuViewController = interactionViewController?.popoverPresentationController
popoverMenuViewController?.permittedArrowDirections = UIPopoverArrowDirection.init(rawValue: 0)
popoverMenuViewController?.sourceView = sender as? UIView
popoverMenuViewController?.popoverBackgroundViewClass = PopupControllerBackgroundView.self
popoverMenuViewController?.sourceRect = CGRect(x: 0,y:0,width: 1,height: 1)
popoverMenuViewController?.delegate = self
self.present(self.interactionViewController!, animated: false, completion: { [weak self] in
self?.interactionViewController?.view.superview?.layer.cornerRadius = 40
self?.interactionViewController?.view.superview?.backgroundColor = .clear
})

Popover presentation in iOS 9

I want to Display a viewController in Popover in iPad . But this line
self.poc = UIPopoverController(contentViewController: sec) deprected in iOS 9
let sec:PopView=PopView(nibName:"PopView",bundle:nil)
self.poc = UIPopoverController(contentViewController: sec)
poc!.delegate=self
self.poc!.presentPopoverFromRect( CGRect(x: 150, y: 222, width: 50, height: 30), inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Right, animated: true)
You need to use UIPopoverPresentationController :
let sec = UIViewController(nibName:"PopView",bundle:nil)
sec.modalPresentationStyle = .Popover
if let secPopoverPresentationController = sec.popoverPresentationController{
secPopoverPresentationController.sourceView = yourSourceView
secPopoverPresentationController.permittedArrowDirections = [.Any]
//Optionally configure other things like sourceRect , delegate ...
}
presentViewController(sec, animated: true, completion: nil)
Hope this helps.

Resources