Use SafariViewController inside a ViewController like UIWebview - ios

I want to use safari cookies to authenticate users for my app. I am able to do it with SFSafariViewController. But the problem is i have UIWebView in my app to show some information. Even though user is logged in using safari, they are asked to login again through UIWebView. I want to sync this. Means if user is logged in by safari he should not have to login again in app.I know that safari and uiwebview don't share cookies and so i want to move everything to safari. Would it be possible to show safari inside of a view controller?
Thanks,
Richa

PopoverViewController method
let vc = SFSafariViewController(url: URL, entersReaderIfAvailable:false)
vc.modalPresentationStyle = .popover
vc.preferredContentSize = CGSize(width: self.view.frame.width/2, height: self.view.frame.height/2) // Or put any size
if let popover = vc.popoverPresentationController {
popover.sourceView = self.view // You can also put the source button
popover.permittedArrowDirections = .any
popover.sourceRect = CGRect(x: 0, y: 0, width: 85, height: 30)
popover.delegate = self
self.present(vc, animated: true, completion: nil)
}
Then declare this subclass:
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate
But this is only work for iPad, so put this:
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
Result

Related

Customize Popover TableView

I am presenting a modal popover view like this:
let popover = StatueSelectionController(collectionViewLayout: UICollectionViewFlowLayout())
popover.delegate = self
popover.modalPresentationStyle = .popover
popover.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem
popover.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.up;
popover.preferredContentSize = CGSize(width: 200, height: 300)
present(popover, animated: true, completion: nil)
The popover.delegate = self has nothing to do with UIPopoverControllerDelegate although it does implement that protocol.
The problem is that the popover takes up the whole view. StatueSelectionController, which is a UICollectionViewController, fills up the whole screen and does not change for preferredContentSize.
What am I doing wrong here?
If you want to force the popOver to not cover the full screen on an iPhone, you would have to add a UIPopoverPresentationControllerDelegate method in your code
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
return .none
}

Dismiss popover viewController when tapped elsewhere

I'm presenting a popover viewController on top of a UITableView. How can i dismiss this popover when tapped outside of it? I'm trying to call it from the didSelectRow method, but the tap isn't detected. Any suggestion?
Thanks!
this is my code:
let addFriendsPopoverViewController = storyboard?.instantiateViewController(withIdentifier: "HomePopOver") as! HomePopOverViewController
addFriendsPopoverViewController.index = (sender.tag)!
addFriendsPopoverViewController.delegate = self
addFriendsPopoverViewController.isModalInPopover = true
addFriendsPopoverViewController.modalPresentationStyle = UIModalPresentationStyle.popover
addFriendsPopoverViewController.preferredContentSize = CGSize(width: 210, height: 40)
let popoverMenuViewController = addFriendsPopoverViewController.popoverPresentationController
popoverMenuViewController!.permittedArrowDirections = .down
popoverMenuViewController!.delegate = self
popoverMenuViewController!.sourceView = self.view
popoverMenuViewController!.sourceRect = CGRect(
x: UIScreen.main.bounds.width - 105,
y: 50,
width: 1,
height: 1)
present(
addFriendsPopoverViewController,
animated: true,
completion: nil)
A view controller presented in a UIPopoverController, or presented using UIModalPresentationPopover, will automatically be dismissed when the user taps outside the popover, unless you have set isModalInPopover or implemented the delegate method which prevents it.
If you need some code to run when this happens, then you'll need to implement a delegate method too.
Which specific methods depend on whether you're using a UIPopoverController or UIModalPresentationPopover. The tags on your question suggest the former, but that's quite an old-fashioned (and deprecated) way of doing it.
Even though you have found your answer, I wanted to share my solution because I had the same problem and after I spent some time to figure it out, I have found what the problem was. It was not actually because of something missing but because of something is implemented in vain.
Although I don't know why it happens but if following method implemented in your code, that may cause popover not to dismiss by tapping anywhere else than UIBarButtonItem itself.
func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
popoverPresentationController.permittedArrowDirections = .any
popoverPresentationController.barButtonItem = UIBarButtonItem(customView: categoryButton)
}
Here's the rest of implementation I have made for popover:
extension SearchViewController:UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
func presentPopover(sender: UIButton) {
let popoverContentController = PopoverCategoryViewController()
let nav = UINavigationController(rootViewController: popoverContentController)
nav.modalPresentationStyle = UIModalPresentationStyle.popover
nav.isNavigationBarHidden = true
let popover = nav.popoverPresentationController
popover?.backgroundColor = ChaptifyColor.backgroundGray
popover?.delegate = self
popover?.sourceView = sender
popover?.sourceRect = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: sender.bounds.width, height: sender.bounds.height))
popoverContentController.preferredContentSize = CGSize(width: 300, height: 300)
self.present(nav, animated: true, completion: nil)
}
}

How to make a window in Xcode

I know this is going to sound confusing but I am making a to-do app for iOS, what I want to do is when a user taps on the add button, instead of user going to another view controller to enter in the new tasks information, I want a little window to pop up in that same view controller where the user can then enter the information. Is their a way to do this?
If i am not wrong you are talking about modal presentation where a view would appear over another view as a popup. This is how it can be done:
let vc = UIStoryboard.storyboard(storyboard: .Vote).instantiateViewController(YourController.self)
under YourController use controller of the popup view
vc.modalPresentationStyle = .popover
let nav = UINavigationController(rootViewController: vc)
nav.modalPresentationStyle = UIModalPresentationStyle.popover
let popover = nav.popoverPresentationController
vc.preferredContentSize = CGSize(width: 280,height: 300) //use own height and width
vc.navigationController?.isNavigationBarHidden = true
popover!.delegate = self
popover!.sourceView = self.view
popover!.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY - 20,width: 0,height: 0)
popover!.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
self.present(nav, animated: true, completion: nil)
this will make the view appear as a popup in your root view

Modify width of Popover View Controller

I am trying modify the width of my popover, which is a UITableViewController, so that it only takes up half of the width of the parent view. The popover is called programmatically when a button in another UITableView (the parent view) is tapped. I tried setting the preferredContentSize of the popover and setting the sourceRect but the popover still takes over the entire screen.
class MyTableViewController: UITableViewController, UICollectionViewDataSource, UICollectionViewDelegate, UIDynamicAnimatorDelegate, UIGestureRecognizerDelegate, CLLocationManagerDelegate, UIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate {
...
func goToPlaces(button: UIButton) {
let fromRect = CGRectMake(50.0, 50.0, self.view.bounds.width / 2.0, self.view.bounds.height)
let popoverVC = storyboard?.instantiateViewControllerWithIdentifier("otherPlaces")
popoverVC?.modalPresentationStyle = .OverFullScreen
presentViewController(popoverVC!, animated: true, completion: nil)
popoverVC?.view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.6)
popoverVC?.preferredContentSize = CGSizeMake(self.view.bounds.width / 2.0, self.view.bounds.height)
let popoverController = popoverVC?.popoverPresentationController
popoverPresentationController?.sourceView = self.view
popoverPresentationController?.sourceRect = fromRect
popoverController?.permittedArrowDirections = .Any
popoverController?.delegate = self
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
EDIT:
When I do a print of
popoverPresentationController?.sourceView and
popoverPresentationController?.sourceRect
they both return nil for some reason
You are asking for
popoverVC?.modalPresentationStyle = .OverFullScreen
so you get it covering the whole screen. Try using:
popoverVC?.modalPresentationStyle = .Popover
The
presentViewController(popoverVC!, animated: true, completion: nil)
should also be last so that the delegate can get the calls for which it wants to respond. (I think -- it might not matter if UIKit is actually delaying the presentation.)
Try using popoverVC.modalPresentationStyle = UIModalPresentationStyle.PageSheet,

Present UISearchBar results as UIPopoverPresentationController iOS 9

I have a ParentViewController with a UISearchBar, and a ChildTableViewController with a tableView where the results from the search will be displayed. When I tap on the searchBar, a popover should present with all the results that conform to the filter written on the searchBar. This means, at the beginning, all results should be displayed in a popoverController.
The problem is that the results are shown occupying the whole screen, instead of being presented in a popover. Below is the code corresponding to ParentViewController where the popover should be presented.
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
let childController = ChildTableViewController()
childController.modalPresentationStyle = .Popover
childController.preferredContentSize = CGSize(width: 50, height: 100)
let popover = childController.popoverPresentationController
popover?.permittedArrowDirections = .Any
popover?.delegate = self
popover?.sourceView = self.view
popover?.sourceRect = CGRect(x: 200, y: 200, width: 1, height: 1)
presentViewController(childController, animated: true,completion: nil)
}
I am using Xcode 7 and iOS 9.
What you need to do is to implement the following method which is part of the UIPopoverPresentationControllerDelegate protocol:
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone; // This will force a popover display
}

Resources