iOS'ta, Xamarin.Forms, kök düğüm bir ScrollView
olduğunda klavye geldiğinde ekranı yeniden boyutlandırır. Ancak kök düğümü ScrollView
değilse, klavye UI'nin bir bölümünü gizler. Bunu nasıl devam ettiriyorsun?Klavyeyi, yeniden boyutlandırmak yerine UI'm kapsamasını nasıl sağlayabilirim?
cevap
Bunu düzeltmenin yolu, klavyenin gösterilmesini dinleyen ve oradayken dolgu ekleyen bir özel oluşturucu ile gerçekleştirilir. senin PCL projede
,KeyboardResizingAwareContentPage.cs
: iOS projesinde
using Xamarin.Forms;
public class KeyboardResizingAwareContentPage : ContentPage {
public bool CancelsTouchesInView = true;
}
, 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);
}
}
}
}
Bu Xamarin Forum question bunu tartışır. Ayrıca
size sadece ana aktivitede bu ayarlayabilirsiniz Xamarin/Formlar kullanan Android bunu istiyorum:
[Activity(WindowSoftInputMode = Android.Views.SoftInput.AdjustResize)]
public class MainActivity
...
Ben KeyboardOverlap plugin Anthony çözümünde daha iyi çalıştığını gördük.
- özel oluşturucusunu
public class KeyboardResizingAwareContentPage : ContentPage
{
}
oluştur
- iOS'ta özel renderer uygulayın:
Bu onu nasıl kullanılacağı.
[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;
}
}
Ve eksik uzantıları::
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;
}
}
- Kullanım özel sayfa oluşturucu
public partial class LoginPage : KeyboardResizingAwareContentPage
{
public LoginPage()
{
// your content
// note: you have to use base.Navigation.PushAsync(), base.DisplayAlert(), ...
}
}
Burada önemli
paulpatarinski kod parçasıdır
<?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>
Bunun için tüm kredi Paul! Bunun için teşekkürler!
Bu çözümün yanı sıra (üretim günlüklerinden): System.ObjectDisposedException: Atılan bir nesneye erişilemiyor.Nesne adı: 'IosKeyboardFixPageRenderer'. –
_isKeyboardShown = false; UnregisterForKeyboardNotifications yönteminin sonunda taşınmalıdır –
- 1. sonra yeniden boyutlandırmak tuval
- 2. WPF, yeniden boyutlandırmak için yeniden boyutlandırmak için ResizeGrip kullanarak
- 3. Duvar Eklentisi: Yeniden boyutlandırmak için yeniden boyutlandırma
- 4. Tarayıcı yeniden boyutlandırıldığında yeniden boyutlandırmak için DIV'yi nasıl alabilirim?
- 5. jQuery boşlukları dinamik olarak yeniden boyutlandırmak için
- 6. Yeniden boyutlandırmak için div kapsayıcısını durdur
- 7. Görüntüyü yeniden boyutlandırmak için kütüphane. Net
- 8. EditText resize yeniden boyutlandırmak için Metin Boyutu
- 9. Otomatik olarak resimleri yeniden boyutlandırmak için yeniden boyutlandırın ancak uzatmayın
- 10. Belirli boyutlar altında formu yeniden boyutlandırmak için kullanıcıya izin ver
- 11. Ansible: ext4 dosya sistemini yeniden boyutlandırmak mümkün mü?
- 12. Android yük çekilebilir programlama ve yeniden boyutlandırmak o
- 13. Klavyeyi göster
- 14. UWP: Görüntüyü yeniden boyutlandırma Nasıl yeniden boyutlandırmak istediğiniz bir Byte [] içinde depolanmış bir JPEG resmim var.
- 15. UICollectionViewController'da GetSizeForItem uygulamasını nasıl sağlayabilirim?
- 16. UISearchbar'a dokunmadan klavyeyi nasıl gösterirsiniz?
- 17. Sublime Text 3 - Bölmeyi Yeniden Boyutlandırmak İçin Kısayol?
- 18. Görüntü PHP sorunu yeniden boyutlandırmak - gd çirkin boyutlandýrýlmýþ görüntü
- 19. Android'de bitmap'leri yeniden boyutlandırmak için en verimli bellek yolu?
- 20. WebView'de sayısal klavyeyi göster
- 21. AdjustResize, klavyeyi dışladıktan sonra klavyeden çıktıktan sonra çalışmıyor
- 22. UISearchBir tıklandığında klavyeyi göstermiyorBaşlarken
- 23. Paperclip'in acts_as_paranoid modelindeki ekleri silmesini nasıl sağlayabilirim?
- 24. Bir etkinliği bitirdikten sonra klavyeyi nasıl çıkarırım?
- 25. Android'de sanal klavyeyi görüntüleyin TabLayout
- 26. iPhone uygulamasında klavyeyi kapatan anahtar (UITextView ile)
- 27. WPF GridSplitter'ın Izgaramın boyutunu değiştirmesini nasıl sağlayabilirim?
- 28. C# uygulamamın bir bölümünü, uygulamanın yeniden başlatılmadan dinamik olarak yüklenmesini nasıl sağlayabilirim?
- 29. Bence son IMG-etiketi içinde kullanım istediğiniz bir görüntüyü yeniden boyutlandırmak nasıl birkaç hile gördüm
- 30. Swift: Kırpmadan sonra görüntüyü yeniden boyutlandırmak için yazdığım kodu nasıl optimize edebilirim?
Sonuç iyi, ancak klavyeyi gizlemek için nasıl yapabilirim? Çünkü klavyenin dışına dokunursam kapanmıyorsa ... –
@ Fran_gg7 ResignFirstResponder() öğesini kullanın. Yani "Klavyeyi etkinleştiren Denetiminiz" ResignFirstResponder(); – Sturla
Xamarin Formlar, sayfada “ResignFirstResponder” öğesini otomatik olarak çağıran bir jest tanıyıcıya sahip olmalıdır. Bazen bu davranışı istemezsiniz, 'CancelsTouchesInView' boolean'ın amacı; Xamarin Forms'ın varsayılan davranışını iptal etmek için false değerine ayarlayın. –