UIContextMenuInteraction : How to Dismiss Manually? - ios

When a UIContextMenuInteraction/UITargetedPreview is visible, is it possible to manually dismiss it? For example, when the app goes to the background, I would like to dismiss it manually.
https://kylebashour.com/posts/context-menu-guide

I was interested in the same thing, and calling UIViewController.dismiss(animated:completion:) on the source view controller dismisses it as it would a modally presented controller.

UIContextMenuInteraction has a method which is called dismissMenu.
I believe this is what you would rather call when in need to hide a menu, because calling dismiss(animated:completion:) could lead to unwanted behaviour if you have another modally presented controller and you are not sure if the menu is active.
Moreover, starting from iOS 13.2 you can get access to contextMenuInteraction as a property of a UICollectionView and call dismissMenu.
contextMenuInteraction is also available as a property for a UITableView starting from iOS 14.0
It becomes quite complicated when your minimal iOS version is 13.0 and you need somehow to dismiss a menu for a cell in a collectionView. This is a bump in the road I am currently having trouble with. I believe the only appropriate way is to create, save and provide a custom PreviewViewController in this method:
collectionView(collectionView: contextMenuConfigurationForItemAt: point:) -> UIContextMenuConfiguration?
When having access to your custom PreviewViewController, you can call dismiss(animated:completion:) method on it whenever you want.

Related

Will utilizing the "Show" in iOS storyboard cause an iOS app to crash?

Summary:
I'm writing a Swift iOS app with a login screen and several other views in a tab view controller. I'm transitioning from one viewcontroller to another via the "control" + left click -> "Show" method. I want to make sure I'm not designing my iOS app incorrectly with memory leaks or other flaws.
Relative Questions:
Does this mean a new view of that ViewController is created each time "Show" is called?
Could this cause a memory leak or the app to crash?
Do I need to unwind the ViewControllers at some point?
What is the best way to unwind a ViewController when launching another ViewController?
It seems what you are talking about is manually creating a Show Segue (a transition, made via the Storyboard with ctrl + click and drag to another ViewController). This is one correct way to create a Segue (transition) from one ViewController to another. To utilize this, you will need to use the left panel on the Storyboard, give this segue an identifier, and use this identifier to preform a segue from the first ViewController to the second in some sort of method or action (like a button click, etc) using the performSegue method:
self.performSegue(withIdentifier: "NameOfSegue", sender: self)
Here's more info on segues from the docs:
https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/UsingSegues.html
You can read even more detail in the "Modifying a Segue’s Behavior at Runtime" section. Here's a quote: "Most of the work happens in the presenting view controller, which manages the transition to the new view controller. The configuration of the new view controller follows essentially the same process as when you create the view controller yourself and present it." Memory leaks shouldn't be an issue here. Unwind segues let you dismiss view controllers that have been presented, but they are not always needed.

Does calling viewController without dismissing it create a second instance?

I have been searching all over the web but I can't seem to find the answer to this.
Currently i am using presentViewController to start new ViewControllers, but on certain view controllers i do not dismiss it and call over it. I currently am not using any navigation controllers or anything like that.
I am just worried that if I call the same viewController again via presentViewController, that the same viewController would have 2 running instances.
Is it possible? Or does the iOS framework automatically reuse the idle viewController?
If so, how do i remove the idle view controllers?
Thank you! (I was holding back my question and tried to find it all over the web, so if you can point me in the right direction, it would be very helpful thanks!)
iOS will not reuse your view controller, you can easily check it yourself by printing your view controller in viewDidLoad, you will notice first that viewDidLoad is called every time, and next that all objects have different addresses.
Unless you create thousand of them, or the navigation of your app doesn’t let you come back to an “idle” view controller, I would not say this is an issue though.
I don’t see any clean way to remove a view controller from the memory without calling “dismiss”. You could try to:
- “refresh” your view with new data.
- use something like UIPageViewController if the workflow of your app allows this kind of behaviour.
- rework the navigation so you can dismiss the view before calling another one
Good luck

Showing master view on some pages and preventing the user from hiding it

I have an iPad app with a UISplitviewController set as the root view controller of UIWindow. The master view controller (i.e. the view controller of the left view) is the UISplitViewController's delegate with the delegate method shouldHideViewController returns YES, this means when the app first launches the left view will be hidden and can be shown (and hidden) by the user gesture, i want to show the master view when i navigate to detail pages and prevent the user from hiding it using the gesture, i've tried to call shouldHideViewController method on the delegate to let it returns NO the second time it got called but this time it has no effect, the master view keeps hidden in detail pages and can be shown with the user gesture.
any ideas to achieve showing of the master view with this scenario would be highly appreciated.
This may only be a partial answer because I'm not sure what you mean that you call shouldHideViewController method on the delegate. My understanding is that only the UISplitView should call this method. If you call it, then it will not effect the UISplitView, because it wasn't what made the call. In other words, the delegate method is used by UISplitView to get some information (and allow you a place to do additional things to other stuff) but it is not used as a way to tell the UISplitView what to perform.
Having said that, at least for the gesture activation/deactivation, I would think that in splitViewController:shouldHideViewController:inOrientation: you could do something like
[svc setPresentsWithGesture:NO];
I don't see any way to programmatically tell the UISplitViewController to display or hide the master view controller because the delegate only tells it if it should proceed in presenting or hiding the master when it is going to try and do that. It does seem like there should be a way to do this though.

iOS: Refresh a ViewController from a popOver

I'm working on a problem where I have a ViewController which opens a popOver when a button is pressed and then in the popOver you can edit some settings which affect the content shown in the mother ViewController (for instance change the color of the View, change a map or a table there). This can be off course called whenever the popOver is dismissed, but it needs to be live up-to-date.
I tried using delegates, where I can pass over data or call a function but the function won't be started on a ViewController wchich isn't active, right?
I also tried NSNotifications but it didn't work either.
I found several questions like this on stackoverflow, but there is no real answer yet:
UIPopoverController button selecting method of another ViewController but not updating its view iOS
Refresh the view controller from popover
Refreshing a view from a popover
Refresh a WebView in a ViewController from another ViewController
how to refresh or reload a uiviewcontroller
Can somebody please explain a generall way with some code snippets how to get this fixed?
Delegation is a fine solution. The target view controller is presumably still visible underneath the popover (which shouldn't fill the screen). In this case when the target receives the delegate callback it can do any updates and refresh its views to update the UI without any limitation. In this situation both view controllers (the 'target' and the popover) would both be classed as 'active' as they are both visible on screen.

UIViewController viewDidAppear after dismiss?

I have an app that uses a storyboard. I am going from the "main view controller" to the others using standard segues, and I am dismissing the other viewControllers with dismissViewController. (note, they are mostly being displayed in form sheet).
Thing is, when it returns to the main view controller, I need to do some cleanup (clear out arrays, reload a tableview and so on). How would I go about doing this, since i cannot use viewDidLoad or viewDidAppear?
I think the best solution it is add block (for example closeActionBlock) for your presented controller and call this block when you hide controller. (How it is implement you can see in Objective-C Block Property with Xcode code completion)

Resources