2012-01-02 15 views
36

मुझे पता है कि इस सवाल से बार-बार पूछा गया है, लेकिन मेरे लिए कुछ भी काम नहीं कर रहा है। आसपास के अधिकांश समाधान काफी पुराने हैं, और बाकी कोड के अविश्वसनीय रूप से विशाल ब्लॉक हैं जो वास्तविक परियोजना कोडिंग के दस गुना बड़े होते हैं। मेरे पास कुछ UITextFields लंबवत हैं, लेकिन जब कीबोर्ड एक को संपादित करने के लिए लॉन्च होता है, तो यह टेक्स्ट फ़ील्ड को कवर करता है। मैं सोच रहा था कि दृश्य को स्क्रॉल करने के लिए एक सरल शुरुआती तरीका है, और फिर संपादन शुरू होने और समाप्त होने पर वापस आ गया है?कीबोर्ड प्रकट होने पर दृश्य को स्क्रॉल करने के लिए कैसे करें?

धन्यवाद।

+0

के संभावित डुप्लिकेट [कैसे जब कुंजीपटल मौजूद है बनाने के लिए एक UITextField ऊपर ले जाएँ] (http://stackoverflow.com/questions/1126726/how-to-make-a-uitextfield-move-up-when -किबोर्ड-मौजूद है) –

उत्तर

28

मैंने ऐसे समाधान किए हैं जो कुंजीपटल अधिसूचना का उपयोग करके स्क्रॉल और गैर-स्क्रॉल दृश्यों के साथ काम करते हैं और वर्तमान पहले उत्तरदाता का पता लगाते हैं, लेकिन कभी-कभी मैं इसके बजाय इस छोटे समाधान का उपयोग करता हूं: पाठ के माध्यम से शुरुआती कीबोर्ड का पता लगाने का सरल तरीका है फील्ड प्रतिनिधि की textViewDidBeginEditing: विधि और संपूर्ण दृश्य को स्थानांतरित करने के लिए। ऐसा करने का सबसे आसान तरीका self.view.bounds.origin.y से -100 (या जो कुछ भी) को बदलने की लाइनों के साथ कुछ है। विपरीत textViewShouldEndEditing: विधि को विपरीत में सेट करने के लिए विधि का उपयोग करें, जो इस मामले में 100 है। bounds बदलना एक सापेक्ष प्रक्रिया है। इसे बदलने के बाद फ्रेम स्थानांतरित हो गया है लेकिन बाउंड मूल अभी भी शून्य है।

+6

धन्यवाद। यह मेरा कोड अब तक है: '- (BOOL) textViewDidBeginEditing: (UITextField *) टेक्स्टफ़िल्ल्ड { [UIView प्रारंभएनीमेशन: शून्य संदर्भ: NULL]; [UIView सेटएनीमेशन अवधि: 0.35 एफ]; सीजीआरईटी फ्रेम = self.view.frame; frame.origin.y = -100; [self.view setFrame: frame]; [UIView प्रतिबद्धएनीमेशन]; } 'लेकिन मुझे एक चेतावनी मिल रही है जो कहती है "नियंत्रण गैर-शून्य कार्य के अंत तक पहुंच जाता है"। मुझे यकीन नहीं है कि इस के आसपास कैसे जाना है, माफ करना, मैं अभी भी इस पर शुरुआत कर रहा हूं। – John

+1

एनपी। यह कहने के लिए कि आप संपादन की अनुमति दे रहे हैं, इस विधि के अंत में 'वापसी YES;' जोड़ें। उस वर्ग दृश्य के लिए इस वर्ग को प्रतिनिधि के रूप में सेट करना न भूलें। UITextFieldDelegates के लिए एक समान विधि है जिसे 'textFieldDidBeginEditing' कहा जाता है: यदि आपको आवश्यकता हो। –

+0

बहुत बढ़िया, यह चाल है, बहुत बहुत धन्यवाद। हालांकि, एक और सवाल यह है कि, मैं इस वर्ग को उस टेक्स्ट व्यू के प्रतिनिधि के रूप में कैसे सेट करूं? क्षमा करें अगर यह एक बेवकूफ सवाल lol। – John

24

चूंकि मुझे यह मिला, मैं टीपीकेबोर्डबोर्डिंग का उपयोग करता हूं - https://github.com/michaeltyson/TPKeyboardAvoiding

यह बहुत अच्छा काम कर रहा है, और सेटअप करने के लिए बहुत आसान है:

  • आपके विचार नियंत्रक के xib में एक UIScrollView जोड़े
  • सेट TPKeyboardAvoidingScrollView (अभी भी xib में करने के लिए स्क्रॉल दृश्य की क्लास, पहचान निरीक्षक के माध्यम से)
  • प्लेस आपके सभी कि पुस्तक दृश्य के भीतर नियंत्रण

आप भी इसे प्रोग्राम के रूप में बना सकते हैं, अगर आप चाहते हैं।


UITableViewController के अंदर एक ही आवश्यकता के लिए एक कक्षा है; यदि आप 4.3 से नीचे आईओएस के संस्करण का समर्थन करते हैं तो केवल इसकी आवश्यकता होती है।

+0

कूल, धन्यवाद, मैं इसे आजमाने की कोशिश कर रहा हूं। यह एक बेवकूफ सवाल हो सकता है, लेकिन मैंने पहले से ही निब स्थापित किया है, निब मैस के शीर्ष पर एक स्क्रॉल व्यू जोड़ देगा? (मैंने छवि दृश्य में पृष्ठभूमि भी सेट की है) – John

+0

बस निब में दृश्य जोड़ें, फिर अपने अन्य तत्वों को दृश्य के अंदर ले जाएं। आपके सभी तत्व गुण (IBOutlet, कॉन्फ़िगरेशन) रखा जाएगा। यदि आप गड़बड़ हो जाते हैं, तो अंतिम चरण रद्द करें (या अपनी नवीनतम प्रतिबद्धता पर वापस जाएं!) – Guillaume

+0

यदि लाइब्रेरी मिशेल टायसन द्वारा की जाती है, तो मैं इसका उपयोग कर रहा हूं। सरल। – abbood

-1

मेरे पास इसमें एक स्क्रॉलव्यू और 3 टेक्स्ट फ़ील्ड हैं।

ज फ़ाइल है::

#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 

मीटर फ़ाइल:

#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

यदि आपके पास एक UITableView या एक UIScrollView इसके लिए मूल्यों को बदलने के लिए बेहतर है frame में परिवर्तन करने के बजाय contentOffset

, 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 विधि जोड़ने की आवश्यकता नहीं।


मैं यह कहने की आवश्यकता नहीं होगी, लेकिन इस के लिए काम करने के लिए अपने UITextField या UITextViewअपने नियंत्रक के एक प्रतिनिधि होना चाहिए।

3

@BenLu और अन्य उपयोगकर्ताओं को, जो समारोह की समस्या का सामना कर रहे बुलाया हो रही कभी नहीं कर रहे हैं निम्नलिखित कारणों से है: प्रतिनिधि inbuild समारोह bydefaults के रूप में वापसी BOOL के बजाय शून्य इस यह कैसे इस प्रकार होना चाहिए:

-(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

पीटर के उत्तर से शुरू, मैंने आईओएस 10.1 के तहत स्विफ्ट 3.0 में निम्नलिखित दृष्टिकोण विकसित किया। मैं इसे टेक्स्ट व्यू के लिए कर रहा हूं, इसलिए मैंने UITextViewDelegate फ़ंक्शन टेक्स्ट ViewDidBeginEditing और textViewDidEndEditing को कार्यान्वित किया है जहां मैं दृश्य की सीमा समायोजित करता हूं। जैसा कि आप देख सकते हैं, मैंने मूल वाई मान को स्क्रॉल करने के लिए एक छोटे पॉजिटिव नंबर पर सेट किया है और फिर मूल स्थिति पर वापस जाने के लिए 0 पर वापस सेट किया है।

यहां मेरे व्यू कंट्रोलर से प्रासंगिक कोड है। आपको एनिमेट करने की आवश्यकता नहीं है, लेकिन यह एक अच्छा स्पर्श जोड़ता है।

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 
     }) 
    } 
} 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^