Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 这是键盘遮挡内容的有效解决方法吗_Ios - Fatal编程技术网

Ios 这是键盘遮挡内容的有效解决方法吗

Ios 这是键盘遮挡内容的有效解决方法吗,ios,Ios,我有一个Tableview,用户可以在其中将值作为自定义单元格之一输入文本字段 苹果公司提供了一些文档,说明如何通过将视图从键盘的垂直方向移开来调整视图内容(),但它依赖于将视图放入UIScrollView。我不能用桌面视图来做这件事 我可以重新设计应用程序,以便使用常用的导航控制器在单独的细节视图中完成输入,但如果可能的话,我希望用户不必进行额外的触摸(并转移到另一个屏幕)。我喜欢“就在我们现在的地方”做这件事 因此,我的解决办法是在底部多放几个tableview单元格,其中包含一个%20左右

我有一个Tableview,用户可以在其中将值作为自定义单元格之一输入文本字段

苹果公司提供了一些文档,说明如何通过将视图从键盘的垂直方向移开来调整视图内容(),但它依赖于将视图放入UIScrollView。我不能用桌面视图来做这件事

我可以重新设计应用程序,以便使用常用的导航控制器在单独的细节视图中完成输入,但如果可能的话,我希望用户不必进行额外的触摸(并转移到另一个屏幕)。我喜欢“就在我们现在的地方”做这件事

因此,我的解决办法是在底部多放几个tableview单元格,其中包含一个%20左右的值,正常使用情况下不应该出现这种奇怪的情况,因为它们只关注可见的内容。 我必须将空格存储在数据源数组中,然后按降序排序,但这没关系


问题是,这是一种良好的做法吗?更可能的是,它是否足以抵挡苹果公司的HIG拒绝?

UITableView是UIScrollView的一个子类,因此应该能够调整内容和滚动视图插入,就像您链接的示例一样。

UITableView是UIScrollView的一个子类,因此,应该能够像链接的示例一样调整内容和滚动视图插入。

我解决此问题的方法是将
UITableView子类化。以下是我所做的:

// AOTableView.h file

typedef enum
{
    AOKeyboardStateUnknown = 0,
    AOKeyboardStateShowing,
    AOKeyboardStateHidden
} AOKeyboardState;

#import <UIKit/UIKit.h>
#import "AOKeyboardState.h"

@interface AOTableView : UITableView
@property (nonatomic) BOOL observeKeyboardNotifications;
@property (nonatomic) AOKeyboardState keyboardState;
@end


// AOTableView.m file

#import "AOTableView.h"

@interface AOTableView(Private)
@property (nonatomic) CGRect frame0;
- (void)setup;
- (void)keyboardWillShow:(NSNotification *)notification;
- (void)keyboardWillHide:(NSNotification *)notification;
@end

@implementation AOTableView

#pragma mark - Object lifecycle

- (void)awakeFromNib
{       
    [self setup];
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
        [self setup];
    }
    return self;
}

- (void)setup
{
    self.contentSize = self.frame.size;
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    _keyboardState = AOKeyboardStateUnknown;
    _frame0 = self.frame;
    _observeKeyboardNotifications = NO;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Custom setters

- (void)setObserveKeyboardNotifications:(BOOL)observeKeyboardNotifications
{
    if (_observeKeyboardNotifications == observeKeyboardNotifications)
        return;

    _observeKeyboardNotifications = observeKeyboardNotifications;

    if (_observeKeyboardNotifications)
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
    else
    {
         [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    }
}

#pragma mark - UIKeyboard Notifications

- (void)keyboardWillShow:(NSNotification *)notification
{
    if (self.keyboardState == AOKeyboardStateShowing)
        return;

    self.frame0 = self.frame;
    self.keyboardState = AOKeyboardStateShowing;

    NSDictionary* info = [notification userInfo];
    CGRect keyboardFrame = CGRectZero;
    [[info objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame];

    CGRect frame = self.frame0;    
    frame.size.height = CGRectGetMinY(keyboardFrame) - CGRectGetMinY(frame);
    self.frame = frame;

    [self scrollToRowAtIndexPath:self.indexPathForSelectedRow atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    [self deselectRowAtIndexPath:self.indexPathForSelectedRow animated:NO];
}

- (void)keyboardWillHide:(NSNotification *)notification
{
    if (self.keyboardState == AOKeyboardStateHidden)
        return;

    self.keyboardState = AOKeyboardStateHidden;
    self.frame = self.frame0;
}
@end
每当用户单击某个单元格时,它就会成为self.indexPathForSelectedRow
单元格。。。因此,
AOTableView
实例会自动将其滚动到

不过,为了让它起作用,我必须在单元格内的
UITextField
上关闭
userInteraction
(否则,设备可能会对用户是否单击单元格或文本字段感到困惑)。相反,当用户选择具有文本字段的单元格时,我会将文本字段告知成为第一响应者,如下所示:

[cell.textField becomeFirstResponder];

我希望这会有所帮助。

我解决这个问题的方法是将
UITableView
子类化。以下是我所做的:

// AOTableView.h file

typedef enum
{
    AOKeyboardStateUnknown = 0,
    AOKeyboardStateShowing,
    AOKeyboardStateHidden
} AOKeyboardState;

#import <UIKit/UIKit.h>
#import "AOKeyboardState.h"

@interface AOTableView : UITableView
@property (nonatomic) BOOL observeKeyboardNotifications;
@property (nonatomic) AOKeyboardState keyboardState;
@end


// AOTableView.m file

#import "AOTableView.h"

@interface AOTableView(Private)
@property (nonatomic) CGRect frame0;
- (void)setup;
- (void)keyboardWillShow:(NSNotification *)notification;
- (void)keyboardWillHide:(NSNotification *)notification;
@end

@implementation AOTableView

#pragma mark - Object lifecycle

- (void)awakeFromNib
{       
    [self setup];
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
        [self setup];
    }
    return self;
}

- (void)setup
{
    self.contentSize = self.frame.size;
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    _keyboardState = AOKeyboardStateUnknown;
    _frame0 = self.frame;
    _observeKeyboardNotifications = NO;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Custom setters

- (void)setObserveKeyboardNotifications:(BOOL)observeKeyboardNotifications
{
    if (_observeKeyboardNotifications == observeKeyboardNotifications)
        return;

    _observeKeyboardNotifications = observeKeyboardNotifications;

    if (_observeKeyboardNotifications)
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
    else
    {
         [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    }
}

#pragma mark - UIKeyboard Notifications

- (void)keyboardWillShow:(NSNotification *)notification
{
    if (self.keyboardState == AOKeyboardStateShowing)
        return;

    self.frame0 = self.frame;
    self.keyboardState = AOKeyboardStateShowing;

    NSDictionary* info = [notification userInfo];
    CGRect keyboardFrame = CGRectZero;
    [[info objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame];

    CGRect frame = self.frame0;    
    frame.size.height = CGRectGetMinY(keyboardFrame) - CGRectGetMinY(frame);
    self.frame = frame;

    [self scrollToRowAtIndexPath:self.indexPathForSelectedRow atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    [self deselectRowAtIndexPath:self.indexPathForSelectedRow animated:NO];
}

- (void)keyboardWillHide:(NSNotification *)notification
{
    if (self.keyboardState == AOKeyboardStateHidden)
        return;

    self.keyboardState = AOKeyboardStateHidden;
    self.frame = self.frame0;
}
@end
每当用户单击某个单元格时,它就会成为self.indexPathForSelectedRow单元格。。。因此,
AOTableView
实例会自动将其滚动到

不过,为了让它起作用,我必须在单元格内的
UITextField
上关闭
userInteraction
(否则,设备可能会对用户是否单击单元格或文本字段感到困惑)。相反,当用户选择具有文本字段的单元格时,我会将文本字段告知成为第一响应者,如下所示:

[cell.textField becomeFirstResponder];

我希望这有帮助。

你不需要额外的电池或任何花哨的东西

由于文本字段位于表格视图单元格内,因此可以使用以下内容:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    UITableViewCell *cell = (UITableViewCell *)textField.superview.superview;
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    return YES;
}
这意味着每次文本字段成为第一响应者时,键盘都会相应地滚动。这利用了表视图作为滚动视图子类的优势

请注意,这假定:

  • 您的(表)视图控制器是文本字段的委托
  • 文本字段是单元格内容视图的子视图,而不是单元格本身。
    • 如果文本字段是单元格的子视图,则上述方法的第一行应仅引用一个superview(即textField.superview)

    • 您不需要额外的电池或任何花哨的东西

      由于文本字段位于表格视图单元格内,因此可以使用以下内容:

      - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
      {
          UITableViewCell *cell = (UITableViewCell *)textField.superview.superview;
          NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
          [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
          return YES;
      }
      
      这意味着每次文本字段成为第一响应者时,键盘都会相应地滚动。这利用了表视图作为滚动视图子类的优势

      请注意,这假定:

      • 您的(表)视图控制器是文本字段的委托
      • 文本字段是单元格内容视图的子视图,而不是单元格本身。
        • 如果文本字段是单元格的子视图,则上述方法的第一行应仅引用一个superview(即textField.superview)

      链接中的示例过于复杂。正如您所提到的,滚动视图是一个表视图子类,因此不需要通知。链接中的示例过于复杂。正如您所提到的,滚动视图是一个表视图子类,因此不需要通知。与此同时,我正在尝试使用UIButton调用UIAlertView,我可以将其设置为远离键盘。为简洁起见,我没有说它是十进制数字类型。因为AlertView还可以有numericPad没有的取消和接受按钮(嗯,我有这样的额外代码,但它肯定会使视图混乱),这可能是一种没有额外触碰和过度导航眩晕的方法。虽然我怀疑这并不是AlertView的真正用途,但我看到了文本条目的使用。然而,你的回答看起来确实像我的初衷是可能的。我试试看。如果你只有两个文本字段,你可以使用带有/UIAlertViewStyleLogin和PasswordInput的警报视图。这将为您提供两个子视图来接受文本。你不必担心键盘的位置。与此同时,我正在尝试使用UIButton调用UIAlertView,我可以将其设置为远离键盘。为简洁起见,我没有说它是十进制数字类型。因为AlertView还可以有numericPad没有的取消和接受按钮(嗯,我有这样的额外代码,但它肯定会使视图混乱),这可能是一种没有额外触碰和过度导航眩晕的方法。虽然我怀疑这并不是AlertView的真正用途,但我看到了文本条目的使用。然而,你的回答看起来确实像我的初衷是可能的。我试试看。如果你只有两个文本字段,你可以使用带有/UIAlertViewStyleLogin和PasswordInput的警报视图。这将为您提供两个子视图来接受文本。你不必担心键盘的位置