In iOS ändert Xamarin.Forms den Bildschirm, wenn die Tastatur hochfährt, wenn der Stammknoten ein ScrollView
ist. Wenn der Stammknoten jedoch kein ScrollView
ist, blendet die Tastatur einen Teil der Benutzeroberfläche aus. Wie verhinderst du das?Wie kann ich verhindern, dass die Tastatur meine Benutzeroberfläche abdeckt, anstatt die Größe zu ändern?
Antwort
Der Weg, um dies zu beheben, ist mit einem benutzerdefinierten Renderer, der auf die Tastatur hört und fügt Polsterung, während es da ist.
In Ihrem PCL Projekt KeyboardResizingAwareContentPage.cs
:
using Xamarin.Forms;
public class KeyboardResizingAwareContentPage : ContentPage {
public bool CancelsTouchesInView = true;
}
In Ihrem iOS-Projekt, IosKeyboardFixPageRenderer.cs
:
using Foundation;
using MyProject.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(KeyboardResizingAwareContentPage), typeof(IosKeyboardFixPageRenderer))]
namespace MyProject.iOS.Renderers {
public class IosKeyboardFixPageRenderer : PageRenderer {
NSObject observerHideKeyboard;
NSObject observerShowKeyboard;
public override void ViewDidLoad()
{
base.ViewDidLoad();
var cp = Element as KeyboardResizingAwareContentPage;
if (cp != null && !cp.CancelsTouchesInView) {
foreach (var g in View.GestureRecognizers) {
g.CancelsTouchesInView = false;
}
}
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
observerHideKeyboard = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, OnKeyboardNotification);
observerShowKeyboard = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, OnKeyboardNotification);
}
public override void ViewWillDisappear(bool animated)
{
base.ViewWillDisappear(animated);
NSNotificationCenter.DefaultCenter.RemoveObserver(observerHideKeyboard);
NSNotificationCenter.DefaultCenter.RemoveObserver(observerShowKeyboard);
}
void OnKeyboardNotification(NSNotification notification)
{
if (!IsViewLoaded) return;
var frameBegin = UIKeyboard.FrameBeginFromNotification(notification);
var frameEnd = UIKeyboard.FrameEndFromNotification(notification);
var page = Element as ContentPage;
if (page != null && !(page.Content is ScrollView)) {
var padding = page.Padding;
page.Padding = new Thickness(padding.Left, padding.Top, padding.Right, padding.Bottom + frameBegin.Top - frameEnd.Top);
}
}
}
}
Diese Xamarin Forum question diskutiert sich.
Außerdem, wenn Sie es in Android wollen Xamarin/Formulare verwenden Sie diese in Ihre Haupttätigkeit nur einstellen:
[Activity(WindowSoftInputMode = Android.Views.SoftInput.AdjustResize)]
public class MainActivity
...
fand ich, dass die KeyboardOverlap plugin funktioniert besser als die Lösung von Anthony. Diese
ist, wie ich es verwenden:
- ein Renderer individuelle Erstellen
public class KeyboardResizingAwareContentPage : ContentPage
{
}
- den benutzerdefinierten Renderer auf iOS implementieren. Hier ist der wichtige Teil der paulpatarinski Code:
[Preserve (AllMembers = true)]
public class KeyboardOverlapRenderer : PageRenderer
{
NSObject _keyboardShowObserver;
NSObject _keyboardHideObserver;
private bool _pageWasShiftedUp;
private double _activeViewBottom;
private bool _isKeyboardShown;
public static void Init()
{
var now = DateTime.Now;
Debug.WriteLine ("Keyboard Overlap plugin initialized {0}", now);
}
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
var page = Element as ContentPage;
if (page != null) {
var contentScrollView = page.Content as ScrollView;
if (contentScrollView != null)
return;
RegisterForKeyboardNotifications();
}
}
public override void ViewWillDisappear (bool animated)
{
base.ViewWillDisappear (animated);
UnregisterForKeyboardNotifications();
}
void RegisterForKeyboardNotifications()
{
if (_keyboardShowObserver == null)
_keyboardShowObserver = NSNotificationCenter.DefaultCenter.AddObserver (UIKeyboard.WillShowNotification, OnKeyboardShow);
if (_keyboardHideObserver == null)
_keyboardHideObserver = NSNotificationCenter.DefaultCenter.AddObserver (UIKeyboard.WillHideNotification, OnKeyboardHide);
}
void UnregisterForKeyboardNotifications()
{
_isKeyboardShown = false;
if (_keyboardShowObserver != null) {
NSNotificationCenter.DefaultCenter.RemoveObserver (_keyboardShowObserver);
_keyboardShowObserver.Dispose();
_keyboardShowObserver = null;
}
if (_keyboardHideObserver != null) {
NSNotificationCenter.DefaultCenter.RemoveObserver (_keyboardHideObserver);
_keyboardHideObserver.Dispose();
_keyboardHideObserver = null;
}
}
protected virtual void OnKeyboardShow (NSNotification notification)
{
if (!IsViewLoaded || _isKeyboardShown)
return;
_isKeyboardShown = true;
var activeView = View.FindFirstResponder();
if (activeView == null)
return;
var keyboardFrame = UIKeyboard.FrameEndFromNotification (notification);
var isOverlapping = activeView.IsKeyboardOverlapping (View, keyboardFrame);
if (!isOverlapping)
return;
if (isOverlapping) {
_activeViewBottom = activeView.GetViewRelativeBottom (View);
ShiftPageUp (keyboardFrame.Height, _activeViewBottom);
}
}
private void OnKeyboardHide (NSNotification notification)
{
if (!IsViewLoaded)
return;
_isKeyboardShown = false;
var keyboardFrame = UIKeyboard.FrameEndFromNotification (notification);
if (_pageWasShiftedUp) {
ShiftPageDown (keyboardFrame.Height, _activeViewBottom);
}
}
private void ShiftPageUp (nfloat keyboardHeight, double activeViewBottom)
{
var pageFrame = Element.Bounds;
var newY = pageFrame.Y + CalculateShiftByAmount (pageFrame.Height, keyboardHeight, activeViewBottom);
Element.LayoutTo (new Rectangle (pageFrame.X, newY,
pageFrame.Width, pageFrame.Height));
_pageWasShiftedUp = true;
}
private void ShiftPageDown (nfloat keyboardHeight, double activeViewBottom)
{
var pageFrame = Element.Bounds;
var newY = pageFrame.Y - CalculateShiftByAmount (pageFrame.Height, keyboardHeight, activeViewBottom);
Element.LayoutTo (new Rectangle (pageFrame.X, newY,
pageFrame.Width, pageFrame.Height));
_pageWasShiftedUp = false;
}
private double CalculateShiftByAmount (double pageHeight, nfloat keyboardHeight, double activeViewBottom)
{
return (pageHeight - activeViewBottom) - keyboardHeight;
}
}
Und die fehlenden Erweiterungen:
public static class ViewExtensions
{
/// <summary>
/// Find the first responder in the <paramref name="view"/>'s subview hierarchy
/// </summary>
/// <param name="view">
/// A <see cref="UIView"/>
/// </param>
/// <returns>
/// A <see cref="UIView"/> that is the first responder or null if there is no first responder
/// </returns>
public static UIView FindFirstResponder (this UIView view)
{
if (view.IsFirstResponder) {
return view;
}
foreach (UIView subView in view.Subviews) {
var firstResponder = subView.FindFirstResponder();
if (firstResponder != null)
return firstResponder;
}
return null;
}
/// <summary>
/// Returns the new view Bottom (Y + Height) coordinates relative to the rootView
/// </summary>
/// <returns>The view relative bottom.</returns>
/// <param name="view">View.</param>
/// <param name="rootView">Root view.</param>
public static double GetViewRelativeBottom (this UIView view, UIView rootView)
{
var viewRelativeCoordinates = rootView.ConvertPointFromView (view.Frame.Location, view);
var activeViewRoundedY = Math.Round (viewRelativeCoordinates.Y, 2);
return activeViewRoundedY + view.Frame.Height;
}
/// <summary>
/// Determines if the UIView is overlapped by the keyboard
/// </summary>
/// <returns><c>true</c> if is keyboard overlapping the specified activeView rootView keyboardFrame; otherwise, <c>false</c>.</returns>
/// <param name="activeView">Active view.</param>
/// <param name="rootView">Root view.</param>
/// <param name="keyboardFrame">Keyboard frame.</param>
public static bool IsKeyboardOverlapping (this UIView activeView, UIView rootView, CGRect keyboardFrame)
{
var activeViewBottom = activeView.GetViewRelativeBottom (rootView);
var pageHeight = rootView.Frame.Height;
var keyboardHeight = keyboardFrame.Height;
var isOverlapping = activeViewBottom >= (pageHeight - keyboardHeight);
return isOverlapping;
}
}
- Verwenden Sie die benutzerdefinierte Seiten Renderer
public partial class LoginPage : KeyboardResizingAwareContentPage
{
public LoginPage()
{
// your content
// note: you have to use base.Navigation.PushAsync(), base.DisplayAlert(), ...
}
}
<?xml version="1.0" encoding="utf-8" ?>
<renderer:KeyboardResizingAwareContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App.Pages.LoginPage"
xmlns:renderer="clr-namespace:App.CustomRenderers;assembly=App">
<!-- your content -->
</renderer:KeyboardResizingAwareContentPage>
Alle Credits dafür gehen an Paul! Danke dafür!
Auch diese Lösung wird ausgelöst (aus Produktionsprotokollen): System.ObjectDisposedException: Zugriff auf ein entsorgtes Objekt nicht möglich.Objektname: 'IosKeyboardFixPageRenderer'. –
_isKeyboardShown = false; sollte am Ende der Methode UnregisterForKeyboardNotifications verschoben werden –
- 1. Bewegung der Benutzeroberfläche verhindern, wenn die Tastatur erscheint
- 2. Wie verhindert man, dass Vollbild die Taskleiste abdeckt?
- 3. Verhindern, dass die Soft-Tastatur verworfen wird
- 4. Verhindern, dass Benutzer die Größe des Fensters/Formulars ändern
- 5. Wie kann ich verhindern, dass Emacs meine Fenster verkleinert?
- 6. Wie kann ich die Benutzeroberfläche problemlos aktualisieren?
- 7. Verhindern Dokument Reflow/Browser Größe ändern, wenn Android-Tastatur öffnet
- 8. Wie verhindern Sie, die Größe der Picturebox zu ändern, wenn Sie die Größe des Steuerelements ändern, das die Picturebox enthält?
- 9. Wie kann ich meine divs davon abhalten, die Größe zu ändern, wenn ich Text hinzufüge/entferne?
- 10. Wie verhindere ich, dass die jquery-Benutzeroberfläche Stile automatisch hinzufügt?
- 11. Wie kann ich verhindern, dass tinyMCE die letzte Fenstergröße speichert?
- 12. Wie kann ich verhindern, dass Backbone.js die OPTIONS-Anfrage sendet?
- 13. Wie kann ich verhindern, dass meine Kontakte zweimal aufgelistet werden?
- 14. Android: Zeige Tastatur bewegt meine Komponenten, ich möchte, dass sie verstecken, anstatt
- 15. So verhindern Sie, dass die Soft-Tastatur bei Berührung erscheint
- 16. Wie kann ich verhindern, dass Emacs meine geteilten Puffer ändert?
- 17. Wie kann ich verhindern, dass meine App mehrmals gestartet wird?
- 18. Wie kann ich verhindern, dass meine App inaktiv wird?
- 19. Wie kann ich verhindern, dass meine TCustomControl-Komponente flackert?
- 20. Wie kann ich die Größe eines Bildes ändern, ohne die Farben in einem Bild zu ändern?
- 21. Wie kann ich verhindern, dass Navigationsschublade meine Aktivität deaktiviert?
- 22. Wie kann ich verhindern, dass meine asp.net-Site gescannt wird?
- 23. Wie kann ich verhindern, dass PerlTidy meine Aufgaben anpasst?
- 24. Wie verhindere ich, dass die Soft-Tastatur meine Ansicht in einem Fragment verschiebt?
- 25. Wie kann ich verhindern, dass sich die Hauptansicht dreht?
- 26. Wie kann ich verhindern, dass die AddressAlreadyInUseException ausgelöst wird?
- 27. mobile Tastatur Größe ändern Ansichtsfenster
- 28. Wie kann ich verhindern, dass die Aktionsleiste abgeschnitten wird?
- 29. C# Wie kann ich verhindern, dass der Benutzer die Größe meines Anwendungsfensters ändert?
- 30. Wie kann ich die Größe von Bildern bei phonegap ändern?
Das Ergebnis ist gut, aber wie kann ich tun, um die Tastatur zu verstecken? Denn wenn ich draußen tippe, schließt sich die Tastatur nicht ... –
@ Fran_gg7 benutze ResignFirstResponder(). Also "Ihr Steuerelement, das die Tastatur aktiviert" ResignFirstResponder(); – Sturla
Xamarin Forms sollte auf der Seite einen Gestenerkenner haben, der automatisch 'ResignFirstResponder' für Sie aufruft. Manchmal möchten Sie dieses Verhalten nicht, für das der 'Bancel'CancelSTouchesInView' ist; Setzen Sie es auf "false", um das Standardverhalten von Xamarin Forms abzubrechen. –