2012-01-02 136 views
36

我知道這個問題一再被問過,但沒有任何東西似乎對我有用。大部分的解決方案都是過時的,其餘的都是非常大的代碼塊,比實際的項目編碼大十倍。我有一些垂直排列的UITextFields,但是當鍵盤啓動編輯一個時,它會覆蓋文本字段。我想知道是否有一個簡單的初學者的方式來滾動視圖,然後在編輯開始和結束時退後?如何在鍵盤出現時向上滾動視圖?

謝謝。

+0

的可能重複[如何使一個的UITextField向上移動時,鍵盤的存在(http://stackoverflow.com/questions/1126726/how-to-make-a-uitextfield-move-up-when -keyboard-is-present) – 2012-01-03 01:51:34

回答

28

我已經制定了解決方案,使用滾動和非滾動視圖使用鍵盤通知和檢測當前第一響應者,但有時我使用這個微不足道的解決方案:簡單的方法是通過文本檢測開放鍵盤現場代表的textViewDidBeginEditing:方法並向上移動整個視圖。最簡單的方法是沿着將self.view.bounds.origin.y更改爲-100(或其他)的方法。使用相應的textViewShouldEndEditing:方法將其設置爲相反,在這種情況下爲100。更改bounds是一個相對的過程。改變它後,框架移動,但邊界原點仍爲零。

+6

謝謝。這是我到目前爲止的代碼:' - (BOOL)textViewDidBeginEditing:(UITextField *)textField {UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.35f]; CGRect frame = self.view.frame; frame.origin.y = -100; [self.view setFrame:frame]; [UIView commitAnimations]; '但是我得到一個警告,說「控制達到非無效功能的結束」。我不知道如何解決這個問題,對不起,我仍然是這方面的初學者。 – John 2012-01-02 23:15:19

+1

np。在方法的末尾添加'return YES;'來表示你允許編輯。不要忘記將此類設置爲該文本視圖的代表。如果你需要的話,有一個叫做「textFieldDidBeginEditing:」的UITextFieldDelegates的相應方法。 – 2012-01-03 00:10:55

+0

太棒了,這個伎倆,非常感謝。但還有一個問題,我如何將該類設置爲該文本視圖的代表?對不起,如果它是一個愚蠢的問題哈哈。 – John 2012-01-03 00:31:02

24

因爲我發現它,我使用TPKeyboardAvoiding - https://github.com/michaeltyson/TPKeyboardAvoiding

這是偉大的工作,而且非常易於安裝:

  • 添加UIScrollView到您的視圖控制器的XIB
  • 設置滾動視圖類TPKeyboardAvoidingScrollView(依然在廈門國際銀行,通過身份檢查)
  • 將所有的滾動視圖中的控件

您也可以通過編程創建它,如果你想。


UITableViewController裏面有同樣需要的類;只有在您支持4.3以下版本的iOS時才需要。

+0

很酷,謝謝,我現在就試試這個。這可能是一個愚蠢的問題,但我已經設置了筆尖,將在筆尖頂部添加一個滾動視圖來搞亂它? (我也在圖像視圖中設置了背景) – John 2012-01-02 23:18:38

+0

只需將視圖添加到筆尖,然後將其他元素移動到視圖中。您的所有元素屬性(IBOutlet,配置)將保留。如果你搞砸了,取消最後一步(或恢復到你最近的提交!) – Guillaume 2012-01-02 23:26:05

+0

如果庫由Micheal Tyson完成,那麼我正在使用它。簡單。 – abbood 2013-08-12 08:10:52

-1

我在這裏有一個滾動視圖和3個文本字段。我有一個簡單的代碼從我自己的應用程序:

h文件是:

#import <UIKit/UIKit.h> 

@interface AddContactViewController : UIViewController<UITextFieldDelegate, UIScrollViewDelegate> 

@property (nonatomic, retain) NSDictionary *dict_contactDetail; 

@property (nonatomic, retain) IBOutlet UILabel *lbl_name; 
@property (nonatomic, retain) IBOutlet UITextField *txtField_tel; 
@property (nonatomic, retain) IBOutlet UITextField *txtField_address; 
@property (nonatomic, retain) IBOutlet UITextField *txtField_email; 

@property (nonatomic, retain) IBOutlet UIScrollView *scrollView; 

@end 

.m文件:

#import "AddContactViewController.h" 

@interface AddContactViewController() 

@end 

@implementation AddContactViewController 

@synthesize dict_contactDetail; 

@synthesize lbl_name, txtField_tel, txtField_email, txtField_address, scrollView; 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view from its nib. 

    // NSLog(@"dict_contactDetail : %@", dict_contactDetail); 

    UIBarButtonItem * rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Add" style:UIBarButtonSystemItemDone target:self action:@selector(addEmergencyContact:)]; 
    self.navigationItem.rightBarButtonItem = rightButton; 


    lbl_name.text = [NSString stringWithFormat:@"%@ %@", [dict_contactDetail valueForKey:@"fname"], [dict_contactDetail valueForKey:@"lname"]]; 

    txtField_tel.returnKeyType = UIReturnKeyDone; 
    txtField_email.returnKeyType = UIReturnKeyDone; 
    txtField_address.returnKeyType = UIReturnKeyDone; 

} 



-(void)addEmergencyContact:(id)sender 
{ 
    scrollView.frame = CGRectMake(0, 0, 320, 460); 
} 

#pragma mark - text field delegates 
- (void)textFieldDidBeginEditing:(UITextField *)textField 
{ 
    if([textField isEqual:txtField_tel]) 
    { 
     [scrollView setContentOffset:CGPointMake(0, 70)]; 
     scrollView.frame = CGRectMake(0, 0, 320, 210); 
    } 
    if([textField isEqual:txtField_address]) 
    { 
     [scrollView setContentOffset:CGPointMake(0, 140)]; 
     scrollView.frame = CGRectMake(0, 0, 320, 210); 
    } 
    if([textField isEqual:txtField_email]) 
    { 
     [scrollView setContentOffset:CGPointMake(0, 210)]; 
     scrollView.frame = CGRectMake(0, 0, 320, 210); 
    } 
} 

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{ 
    scrollView.frame = CGRectMake(0, 0, 320, 460); 
    [textField resignFirstResponder]; 
    return YES; 
} 



@end 
1

我花了一段時間在這個問題上並聚集件代碼來創建一個最終方案。我的問題與UITableView滾動和鍵盤打開/關閉有關。

你需要在你的類中的兩個分部方法:

void EditingBegin(UITextField sender) 
    { 
     // Height of tallest cell, you can ignore this! 
     float tableMargin = 70.0f; 
     float tableHeight = _tableView.Frame.Size.Height; 
     float keyBoardHeight = KeyboardHeight(); 

     NSIndexPath[] paths = this._tableView.IndexPathsForVisibleRows; 
     RectangleF rectLast = this._tableView.RectForSection(paths[paths.Length - 1].Section); 
     RectangleF rectFirst = this._tableView.RectForSection(paths[0].Section); 
     float lastCellY = rectLast.Y - rectFirst.Y; 
     if (lastCellY > tableHeight - keyBoardHeight) 
     { 
      float diff = lastCellY - (tableHeight - tableMargin - keyBoardHeight); 
      this._tableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, diff, 0.0f); 
     } 

     float cellPosition = this._tableView.RectForSection(this._section).Y; 
     if (cellPosition > tableHeight - keyBoardHeight) 
     { 
      if (this._tableView.ContentInset.Bottom == 0.0f) 
      { 
       float diff = cellPosition - (tableHeight - tableMargin - keyBoardHeight); 
       this._tableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, diff, 0.0f); 
      } 
      else 
      { 
       this._tableView.ScrollToRow(NSIndexPath.FromItemSection(0, this._section), UITableViewScrollPosition.Middle, true); 
      } 
     } 
    } 

    partial void EditingEnd(UITextField sender) 
    { 
     UIView.BeginAnimations(null); 
     UIView.SetAnimationDuration(0.3f); 
     this._tableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, 0.0f, 0.0f); 
     UIView.CommitAnimations(); 
    } 

,然後在您的視圖控制器類:

public override void WillAnimateRotation(UIInterfaceOrientation toInterfaceOrientation, double duration) 
    { 
     base.WillAnimateRotation(toInterfaceOrientation, duration); 

     float bottom = this.TableView.ContentInset.Bottom; 
     if (bottom > 0.0f) 
     { 
      if (toInterfaceOrientation == UIInterfaceOrientation.Portrait || toInterfaceOrientation == UIInterfaceOrientation.PortraitUpsideDown) 
      { 
       bottom = bottom * UIScreen.MainScreen.Bounds.Width/UIScreen.MainScreen.Bounds.Height; 
      } 
      else 
      { 
       bottom = bottom * UIScreen.MainScreen.Bounds.Height/UIScreen.MainScreen.Bounds.Width; 
      } 

      UIEdgeInsets insets = this.TableView.ContentInset; 
      this.TableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, bottom, 0.0f); 
     } 
    } 
0

如果你有一個UITableViewUIScrollView它更好地改變值contentOffset而不是對frame進行更改。

工作Peter's Answer,添加此方法類工作得很好:

- (void)textViewDidBeginEditing:(UITextField *)textField { 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.35f]; 
    CGPoint offset = self.tableView.contentOffset; 
    offset.y += 200; // You can change this, but 200 doesn't create any problems 
    [self.tableView setContentOffset:offset]; 
    [UIView commitAnimations]; 
} 

就是這樣,沒有必要添加textViewDidEndEditing方法。


我應該不需要這麼說,但是這個工作你UITextFieldUITextView必須是你的控制器的委託

3

誰面臨的功能問題@BenLu和其他用戶永遠不會獲取調用是因爲以下原因: 作爲委託inbuild功能bydefaults返回void而不是布爾,這是應該的,如下所示:

-(void)textFieldDidBeginEditing:(UITextField *)textField 
{ 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.35f]; 
    CGRect frame = self.view.frame; 
    frame.origin.y = -100; 
    [self.view setFrame:frame]; 
    [UIView commitAnimations]; 
} 

-(void)textFieldDidEndEditing:(UITextField *)textField 
{ 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.35f]; 
    CGRect frame = self.view.frame; 
    frame.origin.y = 100; 
    [self.view setFrame:frame]; 
    [UIView commitAnimations]; 
} 
0

從Peter的回答開始,我在Swift 3.0的iOS 10.1下開發了以下方法。我爲textView做了這個,所以我實現了UITextViewDelegate函數textViewDidBeginEditing和textViewDidEndEditing,我在這裏調整視圖的邊界。如您所見,我將原點Y值設置爲較小的正數以向上滾動,然後返回0以返回原始位置。

這是我的ViewController的相關代碼。你不需要動畫,但它增加了一個很好的接觸。

func textViewDidBeginEditing(_ textView: UITextView) 
{ 
    if UIScreen.main.bounds.height < 568 { 
     UIView.animate(withDuration: 0.75, animations: { 
      self.view.bounds.origin.y = 60 
     }) 
    } 
} 

func textViewDidEndEditing(_ textView: UITextView) 
{ 
    if UIScreen.main.bounds.height < 568 { 
     UIView.animate(withDuration: 0.75, animations: { 
      self.view.bounds.origin.y = 0 
     }) 
    } 
} 
相關問題