3

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

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

这可以通过使用inputAccessoryView.

我在这里阅读了有关它的文档。

该文档非常简短,并说:

“此属性通常用于将附件视图附加到为 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等等,但这主要是一个例子。

任何帮助是极大的赞赏!

4

4 回答 4

9

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

self.mytextField.inputAccessoryView = view;
于 2015-12-09T06:14:25.260 回答
3

inputAccessoryView是类的属性UIResponder。它允许您定义一个自定义输入附件视图,以便在接收者成为第一响应者时显示。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]];

然后这些字段中的每一个都会有一个像这样的自定义附件视图。

于 2015-12-09T07:43:40.977 回答
0

删除,然后在您的 UIViewself.inputAccessoryView = view;之后的任何位置添加以下代码:-(void)viewDidLoad { ... }view

-(void) viewDidLoad {
    ....
}

- (UIView *)inputAccessoryView
{
   return self.view;
}
于 2019-12-05T08:32:40.447 回答
-2

我发布这个答案是为了向其他人展示我的确切代码以及它实际上是多么容易,但是所有功劳都归于 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];

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

于 2015-12-09T10:57:13.583 回答