2014-02-14 31 views
2

我遇到了與UITableView and keyboard scrolling issue中描述的相同的問題,但是我正在使用MonoTouch/Xamarin.iOS編寫C#代碼。花了一點工作纔得到一個可用的C#解決方案,所以我想我會分享。Xamarin解決方案:UITableView和鍵盤滾動問題

我試圖解決的問題:我有一個包含列表視圖以及其他一些按鈕的UIViewController。行本身是自定義視圖,其中包含幾個惰性UILabel和一個接受輸入的UITextView。如果用戶觸摸了屏幕下半部分的其中一個TextView,則鍵盤將覆蓋他們正在編輯的字段。此外,如果它是列表的結尾,您甚至無法手動將其滾動到視圖中。

我從閱讀這個網站的帖子得到了很多幫助,我想回饋一些。從幾個帖子中拉出一些部分,我認爲我有一個(合理)簡單的C#解決方案。我沒有足夠的聲望發表評論,所以我創建了一個問題並回答,希望其他人可以節省一些時間。請參閱下面的我的解決方案,並請讓我知道如果我錯過了一些東西!

回答

4

這裏只是調整鍵盤的相關代碼,並且當用戶在TextView(和鍵盤)之外輕敲時關閉鍵盤。

我應該注意的一點是,我的TableView是在屏幕的最底部,所以我不必弄清楚它是如何與鍵盤重疊的。如果你的TableView下面有東西,你需要添加一些數學。

public partial class myViewController : UIViewController 
{ 
    UITapGestureRecognizer _tap; 
    NSObject _shownotification; 
    NSObject _hidenotification; 

    public myViewController() : base("myViewController", null) 
    { 
     // This code dismisses the keyboard when the user touches anywhere 
     // outside the keyboard. 
     _tap = new UITapGestureRecognizer(); 
     _tap.AddTarget(() =>{ 
      View.EndEditing(true); 
     }); 
     _tap.CancelsTouchesInView = false; 
     View.AddGestureRecognizer(_tap); 
    } 

    public override void ViewWillAppear(bool animated) 
    { 
     base.ViewWillAppear(animated); 

     // Register our callbacks 
     _hidenotification = UIKeyboard.Notifications.ObserveDidHide(HideCallback); 
     _shownotification = UIKeyboard.Notifications.ObserveWillShow(ShowCallback); 
    } 

    public override void ViewWillDisappear(bool animated) 
    { 
     // Unregister the callbacks 
     if (_shownotification != null) 
      _shownotification.Dispose(); 
     if (_hidenotification != null) 
      _hidenotification.Dispose(); 

     base.ViewWillDisappear(animated); 
    } 

    void ShowCallback (object sender, MonoTouch.UIKit.UIKeyboardEventArgs args) 
    { 
     // This happens if the user focuses a textfield outside of the 
     // tableview when the tableview is empty. 
     UIView activeView = this.View.FindFirstResponder(); 
     if ((activeView == null) || (activeView == Customer)) 
      return; 

     // Get the size of the keyboard 
     RectangleF keyboardBounds = args.FrameEnd; 

     // Create an inset and assign it to the tableview 
     UIEdgeInsets contentInsets = new UIEdgeInsets(0.0f, 0.0f, keyboardBounds.Size.Height, 0.0f); 
     myTableView.ContentInset = contentInsets; 
     myTableView.ScrollIndicatorInsets = contentInsets; 

     // Make sure the tapped location is visible. 
     myTableView.ScrollRectToVisible(activeView.Frame, true); 
    } 

    void HideCallback (object sender, MonoTouch.UIKit.UIKeyboardEventArgs args) 
    { 
     // If the tableView's ContentInset is "zero", we don't need to 
     // readjust the size 
     if (myTableView.ContentInset.Top == UIEdgeInsets.Zero.Top) 
      return; 

     // Remove the inset when the keyboard is hidden so that the 
     // TableView will use the whole screen again. 
     UIView.BeginAnimations (""); { 
      UIView.SetAnimationCurve (args.AnimationCurve); 
      UIView.SetAnimationDuration (args.AnimationDuration); 
      var viewFrame = View.Frame; 
      var endRelative = View.ConvertRectFromView (args.FrameEnd, null); 
      viewFrame.Height = endRelative.Y; 
      View.Frame = viewFrame; 

      myTableView.ContentInset = UIEdgeInsets.Zero; 
      myTableView.ScrollIndicatorInsets = UIEdgeInsets.Zero; 
     } UIView.CommitAnimations(); 
    } 
} 

謝謝mickm發佈Objective-C解決方案。

0

稍微修改說明了頁面底部工具欄的高度。另外,一旦「第一響應者」視圖被識別,斷言就會離開foreach循環:

void ShowCallback(object sender, UIKit.UIKeyboardEventArgs args) 
     { 
      // This happens if the user focuses a textfield outside of the 
      // tableview when the tableview is empty. 

      UIView activeView = new UIView(); 
      // Find what opened the keyboard 
      foreach (UIView view in this.View.Subviews) 
      { 
       if (view.IsFirstResponder) 
       { 
        activeView = view; 
        break; 
       } 
      } 

      // Get the size of the keyboard 
      var keyboardBounds = args.FrameEnd; 

      // Create an inset and assign it to the tableview 

      //need to subtract the navbar at the bottom of the scree 
      nfloat toolbarHeight = 0f; 
      if (!this.NavigationController.ToolbarHidden) 
      { 
       toolbarHeight = this.NavigationController.Toolbar.Frame.Height; 
      } 

      nfloat adjustedInset = keyboardBounds.Size.Height - toolbarHeight; 

      UIEdgeInsets contentInsets = new UIEdgeInsets(0.0f, 0.0f, adjustedInset, 0.0f); 
      ExerciseTableView.ContentInset = contentInsets; 
      ExerciseTableView.ScrollIndicatorInsets = contentInsets; 

      // Make sure the tapped location is visible. 
      ExerciseTableView.ScrollRectToVisible(activeView.Frame, true); 
     }