Popover presentation in iOS 9 - ipad

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.

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.

UIActivityViewController animation on iPad

Trying to get an UIActivityViewController to animate like in iOS Photos on iPad:
Code so far:
if UIDevice.current.userInterfaceIdiom == .pad {
activityViewController.preferredContentSize = CGSize(width: 540, height: 720)
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2 - 280, y: UIScreen.main.bounds.height, width: 540, height: 720)
activityViewController.popoverPresentationController?.permittedArrowDirections = []
}
viewController.present(activityViewController, animated: true, completion: nil)
Checking for iPad and setting size and (final) position. That's how far I got. Tried adding an UIView.animate block to animate the view after it is being presented (changinging the initial position of course). Also tried creating a CATransition with activityViewController.view.layer.add(transition, forKey: nil). No success.

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 = []
}

center an indicator view in an alertcontroller programmatically

I am trying to center an activity indicator in an alert controller programmatically but am not seeing the expected outcome.
Attempt:
import NVActivityIndicatorView
public func displayActivityAlertWithCompletion(ViewController: UIViewController, pending: UIAlertController, completionHandler: #escaping ()->())
{
//create an activity indicator
let indicator = NVActivityIndicatorView(frame: CGRect(x: (pending.view.frame.width/2) - 25 , y: 0, width: 50, height: 50))
//indicator.clipsToBounds = true
indicator.type = .ballScaleMultiple
indicator.autoresizingMask = \[.flexibleWidth, .flexibleHeight\]
indicator.color = UIColor(rgba: Palette.loadingColour)
//add the activity indicator as a subview of the alert controller's view
pending.view.addSubview(indicator)
indicator.isUserInteractionEnabled = false
// required otherwise if there buttons in the UIAlertController you will not be able to press them
indicator.startAnimating()
ViewController.present(pending, animated: true, completion: completionHandler)
}
The problem you are facing lies in this line:
let indicator = NVActivityIndicatorView(frame: CGRect(x: (pending.view.frame.width/2) - 25 , y: 0, width: 50, height: 50))
At this point your pending alert controller is not yet presented, and it's frame is not updated.
You will have to update the frame of the indicator after the alert controller was presented, so for example you can do the following.
Replace this line:
ViewController.present(pending, animated: true, completion: completionHandler)
With this:
ViewController.present(pending, animated: true, completion: {
// update frame here:
indicator.frame = CGRect(x: (pending.view.frame.width/2) - 25 , y: 0, width: 50, height: 50)
// and manually call completionHandler:
completionHandler()
})

Swift3: Crash on presenting pop over

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: {
})

Resources