【问题标题】:ios How to add an inputAccessoryView?ios 如何添加一个inputAccessoryView?
【发布时间】:2016-03-14 06:45:05
【问题描述】:

我正在尝试复制 Facebook Messenger 应用程序,其中键盘顶部附有一个 UITextView

由于这个应用程序的性质,我需要附加我的view,而不是在键盘出现时手动上下滚动ScrollView

这可以通过使用inputAccessoryView 来实现。

我阅读了上面的文档here

文档很简短,上面写着:

“此属性通常用于将附件视图附加到系统提供的为 UITextField 和 UITextView 对象呈现的键盘上。

这个只读属性的值为 nil。如果要将自定义控件附加到系统提供的输入视图(例如系统键盘)或自定义输入视图(您在 inputView 属性中提供的),请在 UIResponder 子类中将此属性重新声明为读写。

然后您可以使用此属性来管理自定义附件视图。当接收者成为第一响应者时,响应者基础结构在显示之前将附件视图附加到适当的输入视图。”

我尝试过声明一个属性

@interface CommentViewController ()
@property (nonatomic, readwrite, retain) UIView *inputAccessoryView;
@end

然后设置:

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

    UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 20, 320, 100)];
    [view setBackgroundColor:[UIColor greenColor]];

    self.inputAccessoryView = view;

}

然后我尝试调用这两个:

  1. [self.tableView becomeFirstResponder];

  2. [view becomeFirstResponder];

什么都没有发生。我做错了什么?

*注意 - 额外信息:我正在使用 UITableViewController,我希望将 UIView 附加为 inputAccessoryView。一旦让视图正常工作,我将添加 UITextView 等,但这主要是一个示例。

非常感谢任何帮助!

【问题讨论】:

  • 我已经在我当前的应用程序中实现了类似的功能。请将您的电子邮件 ID 发送给我,我将传递您可以根据您的要求定制的示例代码。

标签: ios objective-c uitableview inputaccessoryview


【解决方案1】:

将输入附件添加到您的 textField 或 textView 而不是纯 UIView。

self.mytextField.inputAccessoryView = view;

【讨论】:

    【解决方案2】:

    inputAccessoryViewUIResponder 类的属性。它允许您定义一个自定义输入附件视图,以便在接收者成为第一响应者时显示。通常应将UIToolBar 的实例设置为附件视图。

    工具栏示例:

    MYInputAccessoryToolbar.h

    typedef void (^MYInputAccessoryToolbarDidDoneTap)(id activeItem);
    
    @interface MYInputAccessoryToolbar : UIToolbar
    
    @property (nonatomic, copy) MYInputAccessoryToolbarDidDoneTap didDoneTapBlock;
    
    + (instancetype)toolbarWithInputItems:(NSArray *)items;
    
    - (instancetype)initWithInputItems:(NSArray *)items;
    - (void)addInputItem:(id)item;
    - (void)goToNextItem;
    - (void)goToPrevItem;
    
    @end
    

    MYInputAccessoryToolbar.m

    @interface MYInputAccessoryToolbar ()
    
    @property (strong, nonatomic) UIBarButtonItem *nextButton;
    @property (strong, nonatomic) UIBarButtonItem *prevButton;
    @property (strong, nonatomic) UIBarButtonItem *doneButton;
    
    @property (nonatomic, copy) NSMutableArray *inputItems;
    
    @property (nonatomic) NSInteger activeItemIndex;
    @property (nonatomic) id activeItem;
    
    @end
    
    @implementation MYInputAccessoryToolbar
    
    + (instancetype)toolbarWithInputItems:(NSArray *)items {
        return [[self alloc] initWithInputItems:items];
    }
    
    #pragma mark - Initializations
    
    - (instancetype)init {
        self = [super init];
        if (self) {
            _inputItems = [NSMutableArray new];
    
            _prevButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:101 target:self action:@selector(prevButtonTaped)];
            _nextButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:102 target:self action:@selector(nextButtonTaped)];
            _doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleBordered target:self action:@selector(doneButtonTaped)];
            [_doneButton setTitleTextAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:17]} forState:UIControlStateNormal];
    
            UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
            fixedSpace.width = 20.0f;
    
            UIBarButtonItem *flexSpace  = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    
            NSArray<UIBarButtonItem *> *barButtons = @[_prevButton, fixedSpace, _nextButton, flexSpace, _doneButton];
    
            [self sizeToFit];
    
            self.items = barButtons;
    
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(itemDidBeginEditing:)
                                                         name:UITextFieldTextDidBeginEditingNotification
                                                       object:nil];
    
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(itemDidBeginEditing:)
                                                         name:UITextViewTextDidBeginEditingNotification
                                                       object:nil];
    
        }
        return self;
    }
    
    - (instancetype) initWithInputItems:(NSArray *)items {
        self = [self init];
    
        for (id item in items) {
            [self addInputItem:item];
        }
    
        return self;
    }
    
    #pragma mark - Accessors
    
    - (void)addInputItem:(id)item {
        if ([item respondsToSelector:@selector(setInputAccessoryView:)]) {
            [item setInputAccessoryView:self];
        }
    
        [_inputItems addObject:item];
    }
    
    #pragma mark - Actions
    
    - (void)itemDidBeginEditing:(NSNotification *)noticifation {
        NSInteger itemIndex = [_inputItems indexOfObject:noticifation.object];
        if (itemIndex != NSNotFound && _activeItem != noticifation.object) {
            _activeItemIndex = itemIndex;
            _activeItem      = noticifation.object;
            [self activeItemChanged];
        }
    }
    
    - (void)activeItemChanged {
        _prevButton.enabled = _activeItemIndex != 0;
        _nextButton.enabled = _activeItemIndex != _inputItems.count - 1;
    }
    
    - (void)prevButtonTaped {
        [self goToPrevItem];
    }
    
    - (void)nextButtonTaped {
        [self goToNextItem];
    }
    
    - (void)goToNextItem {
        [_inputItems[_activeItemIndex + 1] becomeFirstResponder];
    }
    
    - (void)goToPrevItem {
        [_inputItems[_activeItemIndex - 1] becomeFirstResponder];
    }
    
    - (void)doneButtonTaped {
        if (_didDoneTapBlock) {
            _didDoneTapBlock(_activeItem);
        }
        [_activeItem resignFirstResponder];
    }
    
    #pragma mark - Dealloc
    
    - (void)dealloc {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidBeginEditingNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidBeginEditingNotification object:nil];
    }
    
    @end
    

    现在假设我们有一组文本字段和文本视图,我们可以使用它们来初始化工具栏的一个实例。

    MYInputAccessoryToolbar *accessoryToolbar = [MYInputAccessoryToolbar toolbarWithInputItems:@[_passwordCurrentField, _passwordNewField, _passwordVerifyField]];
    

    然后这些字段中的每一个都会有一个自定义附件视图,例如this

    【讨论】:

      【解决方案3】:

      删除self.inputAccessoryView = view;,然后在-(void)viewDidLoad { ... } 之后的任意位置添加以下代码,其中view 是您的UIView:

      -(void) viewDidLoad {
          ....
      }
      
      - (UIView *)inputAccessoryView
      {
         return self.view;
      }
      

      【讨论】:

        【解决方案4】:

        我发布这个答案是为了向其他人展示我的确切代码以及它实际上是多么容易,但是所有功劳都归于 MadNik。

        在您想要键盘的视图控制器类中,在实现中添加以下内容:

        @implementation CommentViewController {
            UIView *toolbar;
            UITextView *commentTextView;
            UIButton *postComment;
        }
        

        toolbar 是停靠在键盘上的实际视图,其余对象位于视图顶部。

        接下来就像启动toolbar 并设置它的框架一样简单:

        toolbar = [[UIView alloc]initWithFrame:CGRectMake(0, self.view.frame.size.height-50, self.view.frame.size.width, 50)];
        
        [toolbar setBackgroundColor:[UIColor whiteColor]];
        

        我使工具栏的框架最初位于视图控制器的底部。

        接下来,我只需在工具栏上启动我想要的其余对象,例如 UITextFieldUIButton。随心所欲地布置它们:

        commentTextView = [[UITextView alloc]initWithFrame:CGRectMake(8, 8, self.view.frame.size.width - 16 - 75, 34)];
        [commentTextView setBackgroundColor:[UIColor colorWithWhite:0.97 alpha:1]];
        commentTextView.layer.cornerRadius = 5;
        [commentTextView setFont:[UIFont fontWithName:@"Avenir Next" size:20]];
        [commentTextView setTextColor:[UIColor colorWithWhite:0.35 alpha:1]];
        
        postComment = [[UIButton alloc]initWithFrame:CGRectMake(self.view.frame.size.width-75, 0, 75, 50)];
        [postComment setTitle:@"Post" forState:UIControlStateNormal];
        [postComment.titleLabel setFont:[UIFont fontWithName:@"Avenir Next" size:20]];
        [postComment setTitleColor:[UIColor colorWithRed:(255/255.0) green:(40/255.0) blue:(80/255.0) alpha:1.0] forState:UIControlStateNormal];
        

        接下来将您的对象添加到您的工具栏:

        [toolbar addSubview:commentTextView];
        [toolbar addSubview:postComment];
        

        现在奇迹发生了:您只需将UITextView 的 inputAccessoryView 设置为您希望停靠在键盘上的任何视图。

        在这种情况下,它是toolbar,因为toolbar 充当了容纳其他所有东西的码头。

        现在您需要做的就是将您的toolbar 添加到您的视图控制器,当您点击UITextView 时,由于它的inputAccessoryView 它是toolbartoolbar 将停靠在键盘上!

        由于我使用的是UITableViewController,所以我必须将我的toolbar 添加到窗口中:

        [[[UIApplication sharedApplication]delegate].window addSubview:toolbar];
        

        如此简单!不需要额外的课程或任何东西!

        【讨论】:

        • 好故事。很长。没用。
        猜你喜欢
        • 1970-01-01
        • 2014-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-21
        • 2015-10-27
        • 1970-01-01
        相关资源
        最近更新 更多