JCDefaultFormInputAccessoryView 0.9.5

JCDefaultFormInputAccessoryView 0.9.5

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最新发布2014年12月

James Coleman 维护。



  • 作者
  • James Coleman

为什么?

我需要在大多数文本字段/视图中添加 Previous/Next/Done 按钮。虽然我找到了几个已经实现这一功能的项目,但它们似乎都没有自动调整视图位置或与 UITableView 实例正确工作(因为它们依赖于在视图加载时所有输入视图都可用,而表格视图的单元格是懒惰加载的。)

什么是?

JCDefaultFormInputAccessoryView 允许您在您的控制器中添加一个包含 Previous/Next/Done 按钮的输入附件视图。一旦配置了响应项列表,JCDefaultFormInputAccessoryView 实例允许用户循环访问输入(就像 Safari 在网页表单中所做的那样),并自动确保键盘不会隐藏输入视图。

Sample application screenshot with keyboard hidden

Sample application screenshot with keyboard shown

示例代码?

您可以在 Demo 目录中找到一个工作样本 iOS Xcode 项目。

如何使用?

注意:如果您想配置自己的工具栏按钮(例如,为了利用此项目的视图滚动代码而不使用下一/前一按钮),您可以通过其 delegate 配置附件视图。附件视图本身采用代理协议,并且是默认代理,因此不需要自定义代理。

#import "JCDefaultFormInputAccessoryView.h"
#import "JCDefaultFormInputAccessoryViewResponderItem.h"

@interface MyTableViewController : UITableViewController

@property (strong, nonatomic) JCDefaultFormInputAccessoryView* inputAccessoryView;

@end

@implementation MyTableViewController

- (void) viewDidLoad {
  [super viewDidLoad];

  self.inputAccessoryView = [JCDefaultFormInputAccessoryView defaultFormInputAccessoryView];

  NSMutableArray* responders = [NSMutableArray new];
  NSUInteger sectionCount = [self.tableView.dataSource numberOfSectionsInTableView:self.tableView];
  for (NSInteger section = 0; section < sectionCount; ++section) {
    NSUInteger rowCount = [self.tableView.dataSource tableView:self.tableView numberOfRowsInSection:section];
    for (NSInteger row = 0; row < rowCount; ++row) {
      NSIndexPath* indexPath = [NSIndexPath indexPathForRow:row inSection:section];
      JCDefaultFormInputAccessoryViewRespondingViewGetter respondingViewGetter = ^UIView *{
        UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
        UITextField* textField;
        for (UIView* subview in cell.contentView.subviews) {
          if ([subview isKindOfClass:[UITextField class]]) {
            textField = (UITextField*)subview;
            break;
          }
        }
        return textField;
      };
      [responders addObject:[JCDefaultFormInputAccessoryViewResponderItem itemWithContainingTableView:self.tableView
                                                                                            indexPath:indexPath
                                                                                 respondingViewGetter:respondingViewGetter]];
    }
  }
  self.inputAccessoryView.responders = responders;
}

@end

帮助!键盘没有关闭:iPad 上的模态表单

iOS 有意不在 iPad 上显示模态表单时隐藏键盘,即使文本输入已经放弃第一响应者状态。这是按照文件记录的 RADAR,是出于设计。但是,有一种方法可以覆盖此行为:在模态表单中展示的 UIViewController 需要从 - (BOOL)disablesAutomaticKeyboardDismissal 返回 NO。这是一个不可设置的属性,因此您可以通过类别在所有 UIViewController 实例上覆盖它,或者使用下面的类别在每个实例级别上设置值。注意:如果您使用此类别,请确保在模态中展示的基本控制器上设置重写值,即使是导航控制器也可以。

UIViewController+JCViewControllerHelpers.h

#import <UIKit/UIKit.h>

@interface UIViewController (JCViewControllerHelpers)

- (void) setDisablesAutomaticKeyboardDismissal:(BOOL)disableDismissal;

@end

UIViewController+JCViewControllerHelpers.m

#import "UIViewController+KCViewControllerHelpers.h"
#import <objc/runtime.h>

@implementation UIViewController (JCViewControllerHelpers)

+ (void) load {
  // Swizzling code from http://stackoverflow.com/a/5372042/1114761
  SEL originalSelector = @selector(disablesAutomaticKeyboardDismissal);
  SEL overrideSelector = @selector(JC_disablesAutomaticKeyboardDismissal);
  Method originalMethod = class_getInstanceMethod(self, originalSelector);
  Method overrideMethod = class_getInstanceMethod(self, overrideSelector);
  if (class_addMethod(self, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
    class_replaceMethod(self, overrideSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
  } else {
    method_exchangeImplementations(originalMethod, overrideMethod);
  }
}

static char disablesAutomaticKeyboardDismissalKey;
- (void) setDisablesAutomaticKeyboardDismissal:(BOOL)disableDismissal {
  objc_setAssociatedObject(self, &disablesAutomaticKeyboardDismissalKey, @(disableDismissal), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL) JC_disablesAutomaticKeyboardDismissal {
  NSNumber* overriddenValue = objc_getAssociatedObject(self, &disablesAutomaticKeyboardDismissalKey);
  if (overriddenValue) {
    return [overriddenValue boolValue];
  } else {
    return self.disablesAutomaticKeyboardDismissal;
  }
}

@end

安装?

此项目包括用于与CocoaPods配合使用的podspec。只需将以下内容添加到您的Podfile文件中,并运行pod install命令。

pod 'JCDefaultFormInputAccessoryView'

...

另外,您可以将该项目Library目录中包含的所有文件添加到Xcode项目中。如果您的项目不使用ARC,您将需要在这些文件上启用ARC。您可以通过添加-fobjc-arc标志来按文件启用ARC,具体方法请参阅StackOverflow上的常见问题

致谢

本项目灵感来源于Cédric Luthi的XCDFormInputAccessoryView项目,可在https://github.com/0xced/XCDFormInputAccessoryView/找到。

许可证

本项目采用MIT许可证。所有版权均由本人保留。

版权(c)2012 James Coleman

在此特此授予任何获得此软件及其相关文档副本(以下简称“软件”)的人员免费使用权,可以不经任何限制地处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可、出售软件的副本,并允许将软件提供给他人使用,前提是必须遵守以下条件:

上述版权声明和本许可声明应包含在软件的所有副本或实质性部分中。

软件按“原样”提供,不包括任何保证,无论是明示的、暗示的还是其他形式的,包括但不限于适销性、特定用途的适用性、非侵权性。在任何情况下,作者或版权所有者都不会对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权诉讼或任何其他诉讼中,该索赔、损害或其他责任是因软件或使用或操作软件而产生的、由其产生的、与其相关的或基于软件或其使用或操作的。