2016-08-10 1 views
1

Ich habe eine Methode ein Collection zu bewegen, wenn zwei Textfelder im Innern durch den Rahmen der iPad-Tastatur verdeckt sind:Wie kann ich eine Ansicht bewegen, um eine UITextField, um zu sehen, wenn die Tastatur vorhanden ist, wenn UICollectionViewFlowLayout mit

private void OnKeyboardNotification(NSNotification notification) 
    { 
     var activeTextField = FindFirstResponder(CollectionView); 

     NSDictionary userInfo = notification.UserInfo; 
     CGSize keyboardSize = ((NSValue)userInfo[UIKeyboard.FrameBeginUserInfoKey]).RectangleFValue.Size; 

     var contentInset = new UIEdgeInsets(0, 0, keyboardSize.Height, 0); 
     CollectionView.ContentInset = contentInset; 
     CollectionView.ScrollIndicatorInsets = contentInset; 

     CGRect oldRect = CollectionView.Frame; 
     CGRect aRect = new CGRect(oldRect.X, oldRect.Y, oldRect.Width, 
            oldRect.Height -= keyboardSize.Height); 
     if (!aRect.Contains(activeTextField.Frame.Location)) 
     { 
      CGPoint scrollPoint = new CGPoint(0, activeTextField.Frame.Location.Y - (keyboardSize.Height - 15)); 
      CollectionView.SetContentOffset(scrollPoint, true); 
     } 
    } 

Ich glaube nicht, dass der Code wie vorgesehen funktioniert. Es ist kompliziert durch die Tatsache, dass ich ein benutzerdefiniertes Layout in einer Unterklasse von UICollectionViewFlowLayout definiert habe. Das Layout ermöglicht es mir, Zellen vertikal scrollen zu lassen, die scharf stellen.

Jedes Mal, wenn ich OnKeyboardNotification anrufen, wird override UICollectionViewLayoutAttributes[] danach im benutzerdefinierten Layout aufgerufen. Ich dachte, dies könnte die Wirkung der Methode aufheben, aber wenn das der Fall ist, wie kann ich dann ändern, wenn UICollectionViewLayoutAttributes[] aufgerufen wird?

public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(CGRect rect) 
    { 
     var array = base.LayoutAttributesForElementsInRect(rect); 
     var visibleRect = new CGRect(CollectionView.ContentOffset, CollectionView.Bounds.Size); 

     foreach (var attributes in array) 
     { 
      if (attributes.Frame.IntersectsWith(rect)) 
      { 
       float distance = (float)(visibleRect.GetMidX() - attributes.Center.X); 
       float normalizedDistance = distance/ACTIVE_DISTANCE; 
       if (Math.Abs(distance) < ACTIVE_DISTANCE) 
       { 
        float zoom = 1 + ZOOM_FACTOR * (1 - Math.Abs(normalizedDistance)); 
        attributes.Transform3D = CATransform3D.MakeScale(zoom, zoom, 1.0f); 
        attributes.ZIndex = 1; 
       } 
      } 
     } 
     return array; 
    } 

Edit:

Hier ist ein Beispiel für das Problem.

Ich habe zwei Felder

und hier, wenn ‚Bearbeitungsmodus‘ eingegeben wird, wird die Tastatur blendet das Altersfeld.

+0

Ich kann Ihnen kein Problem klar, könnten Sie einige Screenshots veröffentlichen, um das Problem zu zeigen? –

+0

Natürlich, bitte sehen Sie meine Bearbeitung – Chucky

Antwort

0

Scheint, wie Sie die Probe von Xamarin Samples verwenden.

UICollectionViewLayoutAttributes wird jedes Mal aufgerufen, wenn Sie die Größe Ihrer UICollectionView ändern.

Ich schlage vor, Sie den Speicherort Ihrer Ansicht zu ändern, anstatt zu ändern Größe in Ihrer OnKeyboardNotification Methode:

CGRect oldRect = CollectionView.Frame; 
    CGRect aRect = new CGRect(oldRect.X, oldRect.Y - keyboardSize.Height, oldRect.Width,oldRect.Height); 

Hoffen, dass es Ihr Problem lösen kann, ich Mitternacht im Moment bin, wenn es nicht funktionieren kann, lassen eine Nachricht, ich werde Letztere überprüfen, wenn morgen früh.

Bearbeiten --------------------------------------------- --------------------

Ich ändern einige Code in der Probe, die Sie verwenden, um den Effekt zu machen.

Zunächst wähle ich die LineLayout in AppDelegate.cs, wie folgt aus:

public override bool FinishedLaunching (UIApplication app, NSDictionary options) 
    { 
     //Don't change anything 

//   simpleCollectionViewController = new SimpleCollectionViewController (flowLayout); 
     simpleCollectionViewController = new SimpleCollectionViewController (lineLayout); 
//   simpleCollectionViewController = new SimpleCollectionViewController (circleLayout); 

     simpleCollectionViewController.CollectionView.ContentInset = new UIEdgeInsets (50, 0, 0, 0); 

     window.RootViewController = simpleCollectionViewController; 
     window.MakeKeyAndVisible(); 

     return true; 
    } 

Und dann füge ich eine statische Eigenschaft zu LineLayout.cs, wie folgt aus:

public class LineLayout : UICollectionViewFlowLayout 
{ 
    private static bool flagForLayout = true; 
    public static bool FlagForLayout { 
     get { 
      return flagForLayout; 
     } 
     set { 
      flagForLayout = value; 
     } 
    } 

    public const float ITEM_SIZE = 200.0f; 
    public const int ACTIVE_DISTANCE = 200; 
    public const float ZOOM_FACTOR = 0.3f; 

    public LineLayout() 
    { 
     //Don't change anything 
    } 

    public override bool ShouldInvalidateLayoutForBoundsChange (CGRect newBounds) 
    { 
     return flagForLayout; 
    } 

    public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect (CGRect rect) 
    { 
     //Don't change anything 
    } 

    public override CGPoint TargetContentOffset (CGPoint proposedContentOffset, CGPoint scrollingVelocity) 
    { 
     //Don't change anything 
    } 

} 

Dann in den SimpleCollectionViewController.cs, füge ich eine UITextField für jede Zelle, wie folgt aus:

public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath) 
    { 
     var animalCell = (AnimalCell)collectionView.DequeueReusableCell (animalCellId, indexPath); 

     var animal = animals [indexPath.Row]; 

     animalCell.Image = animal.Image; 

     animalCell.AddSubview (new UITextField (new CGRect (0, 0, 100, 30)){ BackgroundColor = UIColor.Red }); 

     return animalCell; 
    } 

Und noch in Simpl eCollectionViewController.cs ich einige Code in viewDidLoad Methode hinzufügen und zwei Verfahren fügen Sie die Tastaturanzeige Ereignis zu behandeln, wie folgt aus:

public override void ViewDidLoad() 
    { 
     base.ViewDidLoad(); 

     CollectionView.RegisterClassForCell (typeof(AnimalCell), animalCellId); 
     CollectionView.RegisterClassForSupplementaryView (typeof(Header), UICollectionElementKindSection.Header, headerId); 

     UIMenuController.SharedMenuController.MenuItems = new UIMenuItem[] { 
      new UIMenuItem ("Custom", new Selector ("custom")) 
     }; 

     this.View.AddGestureRecognizer(new UITapGestureRecognizer(()=>{ 
      this.View.EndEditing(true); 
     })); 

     NSNotificationCenter.DefaultCenter.AddObserver(this,new ObjCRuntime.Selector("onKeyboardWillShowNotification:"),UIKeyboard.WillShowNotification,null); 
     NSNotificationCenter.DefaultCenter.AddObserver(this,new ObjCRuntime.Selector("onKeyboardWillHideNotification:"),UIKeyboard.WillHideNotification,null); 

    } 

    [Export("onKeyboardWillShowNotification:")] 
    private void OnKeyboardWillShowNotification(NSNotification notification) 
    { 
     LineLayout.FlagForLayout = false; 
     NSDictionary userInfo = notification.UserInfo; 
     CGSize keyboardSize = ((NSValue)userInfo[UIKeyboard.FrameBeginUserInfoKey]).RectangleFValue.Size; 

     CGRect oldRect = CollectionView.Frame; 
     CGRect aRect = new CGRect(oldRect.X, oldRect.Y - keyboardSize.Height, oldRect.Width, 
      oldRect.Height); 
     this.CollectionView.Frame = aRect; 
    } 

    [Export("onKeyboardWillHideNotification:")] 
    private void OnKeyboardWillHideNotification(NSNotification notification) 
    { 
     LineLayout.FlagForLayout = true; 
     this.CollectionView.Frame = UIScreen.MainScreen.Bounds; 
    } 

Jetzt wird LayoutAttributesForElementsInRect wenn Tastatur Show aufgerufen werden, hoffen, dass es Ihr Problem lösen können.

+0

Danke für Ihre Antwort, Alanc! Ja, ich benutze das Xamarin Sample. Es war sehr hilfreich für das, was ich brauchte. Ich mag den Vorschlag, die Ansicht zu verschieben anstatt die Größe zu ändern. Ich habe den von Ihnen geposteten Code ausprobiert, scheint aber immer noch LayoutAttributesForElementsInRect aufzurufen. Weißt du, wie ich damit aufhören kann, dieses genannt zu werden? – Chucky

+0

Wow, du hast das komplett überarbeitet. Ich werde es versuchen, sobald ich eine Chance habe. Danke, @ Alanc-Liu – Chucky

Verwandte Themen