Is it possible to disable the back navigation menu in iOS 14+?
It can be done by subclassing UIBarButtonItem. Setting the menu to nil on a UIBarButtonItem doesn't work, but you can override the menu property and prevent setting it in the first place.
class BackBarButtonItem: UIBarButtonItem {
@available(iOS 14.0, *)
override var menu: UIMenu? {
set {
// Don't set the menu here
// super.menu = menu
}
get {
return super.menu
}
}
}
Then you can configure the back button in your view controller the way you like, but using BackBarButtonItem instead of UIBarButtonItem.
let backButton = BackBarButtonItem(title: "BACK", style: .plain, target: nil, action: nil)
navigationItem.backBarButtonItem = backButton
This is preferred because you set the backBarButtonItem only once in your view controller's navigation item, and then whatever view controller it will be pushing, the pushed controller will show the back button automatically on the nav bar. If using leftBarButtonItem instead of backBarButtonItem, you will have to set it on every view controller that will be pushed.
Edit:
The back navigation menu that appears on long press is a property of UIBarButtonItem. The back button of a view controller can be customized by setting the navigationItem.backBarButtonItem property and by doing so we can control the menu. The only problem with this approach that I see is losing the localization (translation) of the "Back" string which the system button has.
If you want the disabled menu to be the default behaviour you can implement this in one place, in a UINavigationController subclass conforming to UINavigationControllerDelegate:
class NavigationController: UINavigationController, UINavigationControllerDelegate {
init() {
super.init(rootViewController: ViewController())
delegate = self
}
func navigationController(_ navigationController: UINavigationController,
willShow viewController: UIViewController, animated: Bool) {
let backButton = BackBarButtonItem(title: "Back", style: .plain, target: nil, action: nil)
viewController.navigationItem.backBarButtonItem = backButton
}
}
Use `navigationItem.backButtonDisplayMode = .minimal` with a custom back button image
Okay, I finally figured out all the problems I was having.
Basically, this code works just fine:
override func viewDidLoad() {
super.viewDidLoad()
let backImage = UIImage(named: "backImage")?.withRenderingMode(.alwaysOriginal)
navigationController?.navigationBar.backIndicatorImage = backImage
navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage
navigationItem.backButtonDisplayMode = .minimal
}
But I was having problems with the swipe back gesture not working anymore. Turns out, that's a simulator bug, works fine on device. Then there was the problems that the custom back button image didn't actually show up in my view, because of this:
let appearance = UINavigationBarAppearance()
appearance.backgroundColor = .pageBackground
appearance.titleTextAttributes = [.foregroundColor: UIColor.abbey]
appearance.shadowColor = .clear
navigationBar.scrollEdgeAppearance = appearance
navigationBar.standardAppearance = appearance
navigationBar.compactAppearance = appearance
As soon as you set a custom appearance, that completely wipes away the custom back button image. Simple fix, just set these things directly on the navigationBar without involving the appearance.
And now it all works!
How to disable long-click which opens the Android top menu bar with copy/paste/etc. buttons in Cordova Crosswalk apps?
Looks like this is a bug in Crosswalk, and a PR which fixes it has been submitted:
https://github.com/crosswalk-project/crosswalk/pull/3193
Disabling the context menu on long taps on Android
This should work on 1.6 or later (if I recall correctly). I don't believe there's a workaround for 1.5 or earlier.
<!DOCTYPE html>
<html>
<head>
<script>
function absorbEvent_(event) {
var e = event || window.event;
e.preventDefault && e.preventDefault();
e.stopPropagation && e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
return false;
}
function preventLongPressMenu(node) {
node.ontouchstart = absorbEvent_;
node.ontouchmove = absorbEvent_;
node.ontouchend = absorbEvent_;
node.ontouchcancel = absorbEvent_;
}
function init() {
preventLongPressMenu(document.getElementById('theimage'));
}
</script>
</head>
<body onload="init()">
<img id="theimage" src="http://www.google.com/logos/arthurboyd2010-hp.jpg" width="400">
</body>
</html>
Prevent iOS Webkit Long Press on Link
I think you can disable that popup by setting the CSS -webkit-touch-callout
property to none
on the link. You would do this by editing the HTML or CSS file you're loading, not using Objective-C.
Preventing default context menu on longpress / longclick in mobile Safari (iPad / iPhone)
Thanks to JDandChips for pointing me to the solution. It works perfectly in combination with the longclick plugin. For documentation sake I'll post my own answer to show what I did.
HTML:
<script type="text/javascript"
src="https://raw.github.com/pisi/Longclick/master/jquery.longclick-min.js"></script>
<p><a href="http://www.google.com/">Longclick me!</a></p>
The Javascript already was OK:
function longClickHandler(e){
e.preventDefault();
$("body").append("<p>You longclicked. Nice!</p>");
}
$("p a").longclick(250, longClickHandler);
The fix was to add these rules to the style sheet:
body { -webkit-touch-callout: none !important; }
a { -webkit-user-select: none !important; }
Disabled context menu example.
Mobile Web - Disable long-touch/taphold text selection
Reference:
jsFiddle Demo with Plugin
The above jsFiddle Demo I made uses a Plugin to allow you to prevent any block of text from being selected in Android or iOS devices (along with desktop browsers too).
It's easy to use and here is the sample markup once the jQuery plugin is installed.
Sample HTML:
<p class="notSelectable">This text is not selectable</p>
<p> This text is selectable</p>
Sample jQuery:
$(document).ready(function(){
$('.notSelectable').disableSelection();
});
Plugin code:
$.fn.extend({
disableSelection: function() {
this.each(function() {
this.onselectstart = function() {
return false;
};
this.unselectable = "on";
$(this).css('-moz-user-select', 'none');
$(this).css('-webkit-user-select', 'none');
});
return this;
}
});
Per your message comment: I still need to be able to trigger events (notably, touchstart, touchmove, and touchend) on the elements.
I would simply would use a wrapper that is not affected by this plugin, yet it's text-contents are protected using this plugin.
To allow interaction with a link in a block of text, you can use span tags
for all but the link and add class name .notSelected
for those span tags
only, thus preserving selection and interaction of the anchors link.
Status Update: This updated jsFiddle confirms you concern that perhaps other functions may not work when text-selection is disabled. Shown in this updated jsFiddle is jQuery Click Event listener that will fire a Browser Alert for when the Bold Text is clicked on, even if that Bold Text is not text-selectable.
Related Topics
Swift 3 Filter Array of Dictionaries by String Value of Key in Dictionary
Swift Save Viewcontroller State Using Coder Beyond App Close
Video with Gpuimagechromakeyfilter Has Tint When Played in Transparent Gpuimageview
What Is a Safe Way to Turn Streamed (Utf8) Data into a String
Updating Label Takes Too Long (Swift)
Using Simple Ping in Swift (Ios)
How to Access Property or Method from a Variable
How to Reuse Struct on Swift? or Is There Any Other Way
Please Add the Host Targets for the Embedded Targets to the Podfile
Swift - Uitableview Didselectrowatindexpath & Diddeselectrowatindexpath Add & Remove Indexpath Ids
iPhone Simulator Plays Video, Real Device Won'T
Extending a Delegate from a Base Class
Error "Call Can Throw, But Is Not Marked with 'Try' and the Error Is Not Handled"
Custom Mkoverlayrenderer Drawmaprect Function Not Drawing Polygons
Programmatically Obtaining the Imei or Udid of an iOS Device
How to Crop Image in Circle Shape with Grid Inside Circle
iOS Development App Startup Crash
Uialertcontroller Visible Only When Viewdidappear Has Finished Its Call