Reputation: 1791
I'm doing some drawing on a custom UIView canvas, and rather than having a set of buttons at the bottom of the view to allow the user to select shapes, I'd like to have the user do a long press gesture, then have a popup-type menu appear with different shapes they can choose. I don't see anything like this in xCode, though I'd assume there's something like that in iOS. I don't want the alert popup that shows up when you have low battery and notifications.
I've looked into using a UIPopoverController but I'm a bit confused about some of the other Stack Overflow questions I've read about it, and also about the documentation given by Apple.
Upvotes: 7
Views: 12611
Reputation: 21
I used Masture's method above and it worked for me (thank you!), but a couple of notes for other newbies like myself:
Make sure you put "ShowMenuSegue"
(or whatever you choose) as the identifier for your segue in the Storyboard, and
I had to add
var delegate: MainViewController!
in the MenuViewController (with MainViewController being your source view controller) in order to get tvc.delegate = self
to work
Upvotes: 2
Reputation: 561
I described the steps to achieve floating menu as shown in above image:
segue
from the barButtonItem
to the MenuViewCobtroller
of type 'Present as Popover'In the MenuViewController
override the preferredContentSize
as:
override var preferredContentSize : CGSize
{
get
{
return CGSize(width: 88 , height: 176)
}
set
{
super.preferredContentSize = newValue
}
}
In my case I am returning CGSize
with width 100 and size 200. You can set these values so as to fit your floating menu content properly.
4. In the initial/source view controller, in the prepare(for segue: sender)
method set self
as popoverPresentationController
delegate:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowMenuSegue" {
if let tvc = segue.destination as? MenuViewController
{
tvc.delegate = self
if let ppc = tvc.popoverPresentationController
{
ppc.delegate = self
}
}
}
}
The source view controller must comply to UIPopoverPresentationControllerDelegate
and implement following method:
extension ViewController: UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.none
}
}
That's it. You got the floating menu. Hopefully this will be useful.
Upvotes: 3
Reputation: 2458
After you make a connection of that button with the viewController and popover as a segue you will need to prepare. Here is the following code in order to prepare for the popover segue.
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if let identifier = segue.identifier
{
switch identifier
{
case History.SegueIdentifier:
if let tvc = segue.destinationViewController as? TextViewController
{
if let ppc = tvc.popoverPresentationController
{
ppc.delegate = self
}
tvc.text = "\(diagnosticHistory)"
}
default: break
}
}
}
Do keep in mind that if you have an iPhone the popover will take full screen, so you can fix that using this for let's say a text that takes some particular elements.
This will fix the popover to be exactly the size of the elements you have in your text.
@IBOutlet weak var textView: UITextView!
{
didSet
{
textView.text = text
}
}
var text : String = ""
{
didSet
{
textView?.text = text
}
}
override var preferredContentSize : CGSize
{
get
{
if textView != nil && presentingViewController != nil
{
return textView.sizeThatFits(presentingViewController!.view.bounds.size)
}
else
{
return super.preferredContentSize
}
}
set {super.preferredContentSize = newValue}
}
}
I have those 2 in different view controllers but I guess it will work. You will also need to implement UIPopoverPresentationControllerDelegate
and
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
to your first viewController.
Upvotes: 1