Possible to create a UITableView that appears from the corner of a View Controller - swift

I would like to model a table view after one found in the Todoist app (see below), is it possible to do this without and additional framework? If so how would I go about doing this?

You can create a view controller with a UITableView and present it as UIPopoverPresentationController
let vc = UIViewController()
vc.modalPresentationStyle = .popover
vc.preferredContentSize = CGSize(width: 200, height: 200)
let popUp = vc.popoverPresentationController
popUp?.permittedArrowDirections = .up
popUp?.delegate = self
popUp?.sourceView = sender as! UIView // here set the frame of the button that the arrow points to when popup is shown
present(vc, animated: true, completion: nil)
//
Inside the vc that you presents the popup make it implements the delegate UIPopoverPresentationControllerDelegate and write this method
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}

Related

How to present a ViewController as a Modal Sheet without the background shadow

Is there any way to present a ViewController as a Modal Sheet without the background shadow as shown in the first image below using swift. Is there an easy way or should we need to write custom UIPresentationController? [![The required output][1]][1]
[1]: https://i.stack.imgur.com/QAEEn.png![enter image description here](https://i.stack.imgur.com/q4JD5.jpg)
You can use a smaller size view controller as per your need. Firstly add a class.
class SmallSizePresentationController : UIPresentationController {
override var frameOfPresentedViewInContainerView: CGRect {
get {
guard let theView = containerView else {
return CGRect.zero
}
return CGRect(x: 0, y: theView.bounds.height * (281 / 896), width: theView.bounds.width, height: theView.bounds.height)
}
}
}
Then when you want to present this type of view controller just add the extension of your current view controller.
extension YourCurrentViewController: UIViewControllerTransitioningDelegate {
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return SmallSizePresentationController(presentedViewController: presented, presenting: presenting)
}
}
Then present your new view controller like this
let VC = withoutShadowVC()
VC.transitioningDelegate = self
VC.modalPresentationStyle = .custom
self.present(VC, animated: true, completion: nil)
You can modify the view controller height.

My UIViewcontroller is not filling the entire screen?

I have a very simple app with two UIviewcontrollers. I want to dismiss one and present another one. However, when I do this (code below), the second viewcontroller does not fill the screen, instead it hovers over the top one and can easily get dismissed if you swipe from the top down (you can just about see the first viewcontroller at the top)?
VC-1:
#objc private func picksAction(){
print("picks button pressed")
let layout = UICollectionViewFlowLayout()
let viewController = GridPicksCollectionViewController(collectionViewLayout: layout)
let navController = UINavigationController()
navController.pushViewController(viewController, animated: true)
self.present(navController, animated: true) {}
}
Result:
Set modalPresentationStyle to .fullScreen:
navController.modalPresentationStyle = .fullScreen

Swift | UIViewController not showing as PopUp but Fullscreen

So i have a viewcontroller which is basically an alert window which is supposed to be a popup and be dismissed by the tap on outside its frame.
But whenever i call that VC, it is always displayed as fullscreen and not as a pop up window.
I have tried a couple of ways to do this, namely as mentioned below.
if let exp : String = expiredVehicles[i] {
expiredVehicleNumber = expiredVehicles[i]
let popUpVC = SubscriptionExpired()
popUpVC.modalTransitionStyle = .crossDissolve
popUpVC.modalPresentationStyle = .popover // also tried other presentation styles but none work and it is still fullscreen
popUpVC.view.backgroundColor = UIColor.white.withAlphaComponent(0.8)
self.present(popUpVC, animated: true, completion: nil)
}
in case anyone need to see the definition of that VC, i will be glad to share it
i feel i should mention that the VC to be displayed as a popup is inheriting UIViewController
Any insight that might help would be great.
Thanks for the input
One potential way is to add a tap gesture recognizer to your View, which dismisses the VC.
But this will only be helpful if this popup has read-only info and doesn't require any further action from the user.
func addTapRecognizer(){
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap))
self.view.addGestureRecognizer(tap)
}
#objc func handleTap(){
// dismiss the VC here
}
}
You can call following method to show popup:
let popupVC = SubscriptionExpired()
popupVC.modalPresentationStyle = .overCurrentContext
self.addChild(popupVC)
popupVC.view.frame = self.view.frame
self.view.addSubview(popupVC.view)
popupVC.didMove(toParent: self)
}
Then, for removing that popup you can use:
UIView.animate(withDuration: 0.25, animations: {
self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
self.view.alpha = 0.0
}, completion: { (finished) in
if finished {
self.view.removeFromSuperview()
}
})
In that case I have a button inside popup and whenever that button pressed above method triggers. Can you please try it? I can edit my answer according to your needs.
You need to implement this in you presenting view controller:
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
// Return no adaptive presentation style, use default presentation behaviour
return .none
}
UIPopoverPresentationController displaying popover as full screen

How To Shape Orientation of Ipad-like Popover?

I have 2 questions.
1) Currently, my iPad popover is working but the arrow is pointing downward on top of button. How do I flip it so the arrow points upward and the ViewController is under the button?
2) how do I keep the layout the same if I turn my phone (it will become full screen).
Below is my code for the popover that has emojis.
#IBAction func emojiButtonTapped(_ sender: UIButton) {
let VC = storyboard?.instantiateViewController(withIdentifier: "EmojiController") as! EmojiViewController
VC.preferredContentSize = CGSize(width: 200, height: 100)
let navController = UINavigationController(rootViewController: VC)
navController.modalPresentationStyle = UIModalPresentationStyle.popover
let popOver = navController.popoverPresentationController
popOver?.sourceView = sender
popOver?.sourceRect = sender.bounds
popOver?.delegate = self
self.present(navController, animated: true, completion: nil)
}
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
To answer the first question: You can use the permittedArrowDirections property of the UIPopoverPresentationController to give a hint which arrows you allow. In your case, use UIPopoverArrowDirection.up
The second question I do not quite understand - what do you mean with
how do I keep the layout the same if I turn my phone
What layout?

Disable Dismiss Popover On Background Tap Swift

I have a main view controller called TestViewController that has a button and when you tap the button, it opens a popover view controller. When you tap on the background, the popover gets dismissed which is what I want to disable. I have this code in my popover view controller and it should run but it's not running.
extension TestViewController: UIPopoverPresentationControllerDelegate {
func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool {
print ("TEST") //This does not show up in console
return false
}
}
EDIT:
This is the code that I use to open the popover.
let popover = storyboard?.instantiateViewController(withIdentifier: "PopoverVC") as! PopOverViewController
popover.modalPresentationStyle = .popover
popover.popoverPresentationController?.sourceView = self.view
popover.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popover.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
popoverPresentationController?.passthroughViews = nil
popover.dimView2 = self.dimView2
dimView2.isHidden = false
self.present(popover, animated: false)
}
Set the delegate.
popover.popoverPresentationController?.delegate = self
popoverPresentationControllerShouldDismissPopover function is deprecated in iOS 14.
For latest version you should use following code
extension TestViewController: UIPopoverPresentationControllerDelegate {
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
return false
}
}