自动向上滚动文本字段,实现类中没有任何逻辑

Posted

技术标签:

【中文标题】自动向上滚动文本字段,实现类中没有任何逻辑【英文标题】:Automaticallly scroll the textfield upward with out any logic in implementation class 【发布时间】:2014-11-05 05:04:27 【问题描述】:

我有一个带有文本字段的表格视图,当在文本字段中输入文本时,文本字段应该自动向上移动,就在键盘上方。

我在 *** 中看到了许多在文本字段委托方法中编写逻辑的解决方案。

我想分享在键盘上方移动文本字段的解决方案没有任何逻辑。

本帖是为大家分享解决方法。

这个解决方案和这个'How to make a UITextField move up when keyboard is present?'不一样

提前致谢。

【问题讨论】:

怎么可能没有逻辑?必须知道如何滚动视图以移动文本字段。 逻辑将在 customtableviewcell 中,从那里相同的委托将在实现的类中触发 试试这个 (github.com/michaeltyson/TPKeyboardAvoiding)。也许这会对你有所帮助。 所以看来你这个问题的意图是你可以发布你自己的实现作为答案。这很好,但你需要改写你的问题,这样它作为一个问题才有意义。按照现在的措辞,它令人困惑,没有其他人知道如何提供答案。 请提出改写建议,这对所有人都有帮助 【参考方案1】:

我使用LHSKeyboardAdjusting,它不会占用您的UITextField 委托方法。许多库会接管您的委托,因此当-[UITextFieldDelegate textFieldShouldReturn:] 被触发时,您无法执行诸如前进到下一个文本字段之类的操作。

LHSKeyboardAdjusting 监听键盘显示/隐藏事件并调整您传入的视图的底部约束。很酷的是这适用于 UIViewUIScrollView

在您的UIViewController 子类中,这是您设置它的方式(在这种情况下,我在xibstoryboard 中使用UIScrollView):

#import "UIViewControllerSubclass.h"
#import <LHSKeyboardAdjusting/UIViewController+LHSKeyboardAdjustment.h>

@interface UIViewControllerSubclass () <LHSKeyboardAdjusting>

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

/** The constraint that anchors '_scrollView' bottom to '_view' bottom */
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *scrollViewBottomConstraint;

@end

@implementation UIViewControllerSubclass

- (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];

    [self lhs_activateKeyboardAdjustment];


- (void)viewWillDisappear:(BOOL)animated 
    [super viewWillDisappear:animated];

    [self lhs_deactivateKeyboardAdjustment];


#pragma mark - LHSKeyboardAdjusting

- (NSLayoutConstraint *)keyboardAdjustingBottomConstraint 
    return self.scrollViewBottomConstraint;


@end

【讨论】:

【参考方案2】:

以下是customcell文件 //.h 文件

#import <UIKit/UIKit.h>
@protocol TextFieldScrollToVisibleDelegate
@optional
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
- (void)textFieldDidBeginEditing:(UITextField *)textField;
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField;
- (void)textFieldDidEndEditing:(UITextField *)textField;
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
- (BOOL)textFieldShouldClear:(UITextField *)textField;
- (BOOL)textFieldShouldReturn:(UITextField *)textField;


- (BOOL)textViewShouldBeginEditing:(UITextView *)textView;
- (BOOL)textViewShouldEndEditing:(UITextView *)textView;

- (void)textViewDidBeginEditing:(UITextView *)textView;
- (void)textViewDidEndEditing:(UITextView *)textView;

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
- (void)textViewDidChange:(UITextView *)textView;

- (void)textViewDidChangeSelection:(UITextView *)textView;

@end
@interface CustomTableViewCell : UITableViewCell <UITextFieldDelegate,UITextViewDelegate>
@property (nonatomic, assign) NSObject <TextFieldScrollToVisibleDelegate> *mTextFieldScrollToVisibleDelegate_;
@property (nonatomic)  int paddingabovekeyboard;
@end

//.m 文件

#import "CustomTableViewCell.h"
@interface CustomTableViewCell ()
@property (nonatomic)int keyboardHeight;
@property (nonatomic)BOOL useSecondMode;
@property (nonatomic)int actualViewHeight;
@property (nonatomic)int actualViewWidth;
@property (nonatomic)int previousYposition;
@end
#define kKeyboardHeightValue (keyboardHeight==0)?250:keyboardHeight
@implementation CustomTableViewCell
@synthesize mTextFieldScrollToVisibleDelegate_;
@synthesize paddingabovekeyboard;

@synthesize keyboardHeight;
@synthesize useSecondMode;
@synthesize actualViewHeight;
@synthesize actualViewWidth;
@synthesize previousYposition;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) 
        // Initialization code
        paddingabovekeyboard=50;
    
    return self;

-(void)wheatherFirstModeOrsecondMode 
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    BOOL statusBarHidden = [UIApplication sharedApplication].statusBarHidden;
    int statusHight= 20;
    if(statusBarHidden) 
        statusHight=0;
    
    int navheight=0;
    id nav = [UIApplication sharedApplication].keyWindow.rootViewController;
    if ([nav isKindOfClass:[UINavigationController class]]) 
        UINavigationController *navc = (UINavigationController *) nav;
        if(!navc.navigationBarHidden) 
            navheight=44;
        
    
    if(UI_USER_INTERFACE_IDIOM () ==UIUserInterfaceIdiomPhone )
    
        if(orientation == 0||orientation == UIInterfaceOrientationPortrait) 
            keyboardHeight = 216+paddingabovekeyboard; //44
            actualViewHeight= [[UIScreen mainScreen]bounds].size.height-statusHight-navheight;
            actualViewWidth =[[UIScreen mainScreen]bounds].size.width;
          else if(orientation == UIInterfaceOrientationLandscapeLeft||orientation == UIInterfaceOrientationLandscapeRight) 
            keyboardHeight = 162+paddingabovekeyboard; //444
            actualViewHeight= [[UIScreen mainScreen]bounds].size.width-statusHight-navheight;
            actualViewWidth =[[UIScreen mainScreen]bounds].size.height;
        
     else if (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPad)
        if(orientation == 0||orientation == UIInterfaceOrientationPortrait) 
            keyboardHeight = 264+paddingabovekeyboard; //44
            actualViewHeight= [[UIScreen mainScreen]bounds].size.height-statusHight-navheight;
            actualViewWidth =[[UIScreen mainScreen]bounds].size.width;

          else if(orientation == UIInterfaceOrientationLandscapeLeft||orientation == UIInterfaceOrientationLandscapeRight) 
            keyboardHeight = 352+paddingabovekeyboard;//44
            actualViewHeight= [[UIScreen mainScreen]bounds].size.width-statusHight-navheight;
            actualViewWidth =[[UIScreen mainScreen]bounds].size.height;

        
    
    UITableView *myTableView = (UITableView *)[self superview];
    if(![myTableView isKindOfClass:[UITableView class]]) 
        myTableView = (UITableView *)[[self superview] superview];
    
    if(![myTableView isKindOfClass:[UITableView class]]) 
        myTableView = (UITableView *)[[[self superview] superview] superview];
    
    NSLog(@"keyboardHeight %dactualViewHeight%d",keyboardHeight,actualViewHeight);
    if(myTableView.frame.origin.y>actualViewHeight-keyboardHeight-50) 
        useSecondMode=TRUE;
     else 
        useSecondMode=FALSE;
    
#undef kKeyboardHeightValue
#define kKeyboardHeightValue (keyboardHeight==0)?250:keyboardHeight


- (void)setSelected:(BOOL)selected animated:(BOOL)animated

    [super setSelected:selected animated:animated];

    // Configure the view for the selected state

- (void)textFieldDidBeginEditing:(UITextField *)textField 
    @try 
        UITableView *myTableView = (UITableView *)[self superview];
        if(![myTableView isKindOfClass:[UITableView class]]) 
            myTableView = (UITableView *)[[self superview] superview];
        
        if(![myTableView isKindOfClass:[UITableView class]]) 
            myTableView = (UITableView *)[[[self superview] superview] superview];
        
        int scrollpadding;
        if(!self.useSecondMode) 
            scrollpadding=actualViewHeight - (myTableView.frame.origin.y+myTableView.frame.size.height);
            scrollpadding = kKeyboardHeightValue-scrollpadding;
         else 
            CGRect lframe= myTableView.superview.frame;
            self.previousYposition=myTableView.superview.frame.origin.y;

            int heighttochange=0;
            if(myTableView.frame.origin.y<myTableView.frame.size.height) 
                heighttochange = myTableView.frame.size.height;
             else 
                heighttochange = myTableView.frame.origin.y;

            
            int temp = actualViewHeight- keyboardHeight;
            temp = self.frame.origin.y - temp+50;
            heighttochange = (heighttochange>temp)?temp:heighttochange;
            lframe.origin.y-=heighttochange;
            self.superview.frame=lframe;

            scrollpadding =actualViewHeight - ((myTableView.frame.origin.y+lframe.origin.y)+myTableView.frame.size.height);
            scrollpadding = kKeyboardHeightValue-scrollpadding;
        

        UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, scrollpadding, 0.0);
        myTableView.contentInset = contentInsets;
        myTableView.scrollIndicatorInsets = contentInsets;
        CGRect lFrame=[myTableView convertRect:textField.bounds fromView:textField];
        [myTableView scrollRectToVisible:lFrame animated:NO];

        if (nil != mTextFieldScrollToVisibleDelegate_ && [mTextFieldScrollToVisibleDelegate_ respondsToSelector:@selector(textFieldDidBeginEditing:)]) 
            [mTextFieldScrollToVisibleDelegate_ textFieldDidBeginEditing:textField];
        
    
    @catch (NSException *exception) 
    
    @finally 
    


- (void)textFieldDidEndEditing:(UITextField *)textField 
    @try 
        UITableView *myTableView = (UITableView *)[self superview];
        if(![myTableView isKindOfClass:[UITableView class]]) 
            myTableView = (UITableView *)[[self superview] superview];
        
        if(![myTableView isKindOfClass:[UITableView class]]) 
            myTableView = (UITableView *)[[[self superview] superview] superview];
        

        if(!useSecondMode) 
            UIEdgeInsets contentInsets = UIEdgeInsetsZero;
            myTableView.contentInset = contentInsets;
            myTableView.scrollIndicatorInsets = contentInsets;
         else 
            CGRect lframe= self.superview.frame;
            lframe.origin.y=self.previousYposition;
            self.superview.frame=lframe;
            UIEdgeInsets contentInsets = UIEdgeInsetsZero;
            myTableView.contentInset = contentInsets;
            myTableView.scrollIndicatorInsets = contentInsets;
        
        if (nil != mTextFieldScrollToVisibleDelegate_ && [mTextFieldScrollToVisibleDelegate_ respondsToSelector:@selector(textFieldDidEndEditing:)]) 
            [mTextFieldScrollToVisibleDelegate_ textFieldDidEndEditing:textField];
        
    
    @catch (NSException *exception) 
    
    @finally 
    


- (BOOL)textFieldShouldReturn:(UITextField *)textField 
    @try 
        UITableView *myTableView = (UITableView *)[self superview];
        if(![myTableView isKindOfClass:[UITableView class]]) 
            myTableView = (UITableView *)[[self superview] superview];
        
        if(![myTableView isKindOfClass:[UITableView class]]) 
            myTableView = (UITableView *)[[[self superview] superview] superview];
        
        UITableViewCell *cell =((UITableViewCell*)[[textField superview] superview]);
        if(![cell isKindOfClass:[UITableViewCell class]]) 
            cell = (UITableViewCell *)[[[textField superview]superview] superview];
        
        if(!useSecondMode) 
            UIEdgeInsets contentInsets = UIEdgeInsetsZero;
            myTableView.contentInset = contentInsets;
            myTableView.scrollIndicatorInsets = contentInsets;
         else 
            CGRect lframe= self.superview.frame;
            lframe.origin.y=self.previousYposition;
            self.superview.frame=lframe;
            UIEdgeInsets contentInsets = UIEdgeInsetsZero;
            myTableView.contentInset = contentInsets;
            myTableView.scrollIndicatorInsets = contentInsets;
        
        [textField resignFirstResponder];

        if (nil != mTextFieldScrollToVisibleDelegate_ && [mTextFieldScrollToVisibleDelegate_ respondsToSelector:@selector(textFieldShouldReturn:)]) 
            return [mTextFieldScrollToVisibleDelegate_ textFieldShouldReturn:textField];
        
        return YES;
    
    @catch (NSException *exception) 
    
    @finally 
    


- (BOOL)textFieldShouldEndEditing:(UITextField *)textField 
    if (nil != mTextFieldScrollToVisibleDelegate_ && [mTextFieldScrollToVisibleDelegate_ respondsToSelector:@selector(textFieldShouldEndEditing:)]) 
        return [mTextFieldScrollToVisibleDelegate_ textFieldShouldEndEditing:textField];
    
    return YES;


- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
    [self wheatherFirstModeOrsecondMode];

    if (nil != mTextFieldScrollToVisibleDelegate_ && [mTextFieldScrollToVisibleDelegate_ respondsToSelector:@selector(textFieldShouldBeginEditing:)]) 
        return [mTextFieldScrollToVisibleDelegate_ textFieldShouldBeginEditing:textField];
    
    return YES;


- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 

    if (nil != mTextFieldScrollToVisibleDelegate_ && [mTextFieldScrollToVisibleDelegate_ respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) 
        return [mTextFieldScrollToVisibleDelegate_ textField:textField shouldChangeCharactersInRange:range replacementString:string];
    
    return YES;


@end

将上述两个自定义单元格文件添加到您的项目中

下面是如何实现

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    static NSString *CellIdentifier = @"Cell";
    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) 
        cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        UITextField *ltext = [[UITextField alloc] initWithFrame:CGRectMake(10, 2, 120, 30)];
        ltext.borderStyle = UITextBorderStyleLine;
        ltext.delegate=cell;
        cell.mTextFieldScrollToVisibleDelegate_=self;
        ltext.tag=1;
        [cell.contentView addSubview:ltext];

    
    cell.paddingabovekeyboard=44;

    return cell;

上面代码的解释 使用 CustomTableViewCell 代替 UITableViewCell。

注意:此代码仅适用于表格视图中的文本字段

【讨论】:

这是很多逻辑。你的问题说你希望它没有逻辑地完成。 在实现类中,文本字段委托将没有逻辑

以上是关于自动向上滚动文本字段,实现类中没有任何逻辑的主要内容,如果未能解决你的问题,请参考以下文章

单击文本字段时防止表单向上滚动

当焦点和键盘隐藏文本字段时滚动到文本字段

当键盘出现并启用滚动时,TextField 向上移动

如何在 UIView 中设置滚动视图以向上滑动被键盘隐藏的文本字段?

Kivy Scrollview 自动滚动到新文本。防止向上滚动

Flutter :启用文本字段时,背景图像向上移动。 “resizeToAvoidBottomInset”禁用滚动。我哪里错了?