iOS-Entwicklung: Wie verhindere ich den Bounce-Effekt bei UIWebView und sperre das Kontext-Menü

iOS-Entwicklung: Wie verhindere ich den Bounce-Effekt bei UIWebView und sperre das Kontext-Menü

UIWebKit

Beim entwickeln des Mobilen MwSt-Rechners, der kurz vor dem Update-Release steht (nur noch die Hilfe muss überarbeitet werden), ist mir aufgefallen, wie praktisch einerseits das UIWebView für die Darstellung von formatierten Inhalten ist und welche Nachteile das UIWebView mit sich bringt.

Einer der ersten Effekte, die einem direkt auffallen ist der sogenannte Bounce-Effekt, wenn man an die Ende der Seite kommt. Ein Verhalten, was beim normalen ScrollView nur auf gezieltem Wunsch aktiviert wird. UIWebKit kennt dagegen keinen offiziellen Aufruf, der ein solches Verhalten verhindert.

Je nach Einsatzzweck ist auch ein zweiter Effekt nicht unbedingt erwünscht. Wer länger auf auf eine Textstelle tippt, für den öffnet sich ein Kontextmenü um Inhalte des UIWebView in die Zwischenablage zu übernehmen. Möchte man dieses Verhalten verhindern, so kann man natürlich die Nutzer-Interaktion mit dem UIWebKit einfach unterbinden. Wer allerdings Links auf der Webseite hat, der wird schnell bemerken, dass diese ebenfalls für den Benutzer gesperrt sind.

Für beide Problemsituationen gibt es mittlerweile brauchbare Lösungen, welche auf undokumentierte API Aufrufe verzichten.

Problem 1) Das sperren des Zwischenablage-Menüs:

Ist es überraschend, dass die Lösung hierfür nicht im Programmcode selber, sondern in der anzuzeigenden HTML-Seite selber liegt? Die Lösung liegt hier in einem kleinen Javascript, welches das Menü sperrt:

[cc escaped=„true” lang=„javascript” nowrap=„false” line_numbers=„true”]
<script type=„text/javascript”><![CDATA[
function blockCallouts() {
//Callouts sperren
document.documentElement.style.webkitTouchCallout = „none”;
document.documentElement.style.webkitUserSelect = „none”;
}
]]></script>
[/cc]

Das Javascript sollte in den Header-Bereich der Seite und per <body onload=„blockCallouts()”> beim Aufruf der Seite automatisch aktiviert werden.

In diesem Zusammenhang ist folgender Tipp eventuell noch von Interesse. Wer gerne möchte, dass die Pseudo-Klasse :hover in den Stylesheets auf Touch-Ereignisse reagiert, für den bietet sich eine kleine Erweiterung des Scripts an:

[cc escaped=„true” lang=„javascript” nowrap=„false” line_numbers=„true”]
<script type=„text/javascript”><![CDATA[
function blockCallouts() {
//Callouts sperren
document.documentElement.style.webkitTouchCallout = „none”;
document.documentElement.style.webkitUserSelect = „none”;

//Hover Support fuer Touch-Events aktivieren
var documentLinks = document.getElementsByTagName(‘a’);
for(var i = 0; i < documentLinks.length; i++){
documentLinks[i].addEventListener(‘touchstart’, function(event) {
this.className = „hover”;
}, false);

documentLinks[i].addEventListener(‘touchstop’, function(event) {
this.className = „”;
}, false);
}
}
]]></script>
[/cc]

 

Problem 2) Bouncing UIWebKit:

Im Gegensatz zur vorhergehenden Problemlösung, muss hier tatsächlich mit etwas Objective‑C Code gearbeitet werden. Der Code selber ist allerdings relativ einfach und kurz. Nehmen wir für unser Beispiel an, dass das UIWebKit-Element auf den Namen „helpBrowser” hört.

[cc escaped=„true” lang=„objc” nowrap=„false” line_numbers=„true”]
//Prevent bouncing
for (id subview in helpBrowser.subviews){
if ([[subview class] isSubclassOfClass: [UIScrollView class]])
((UIScrollView *)subview).bounces = NO;
}
[/cc]

Sinnvollerweise sollte der Programmcode zum deaktivieren des Bounce-Effekts beim laden des Views aufgerufen werden. Hierfür bietet sich viewDidLoad(); an.

 

Für Fragen oder Vorschläge zu diesen Code-Schnipsel steht das Kommentarsystem selbstverständlich zur Verfügung.