我正在尝试复制Facebook Messenger App,其中键盘顶部附有UITextView
。
由于此应用的性质,我需要附加view
,而不是在键盘出现时手动向上和向下滚动ScrollView
。
这可以通过使用inputAccessoryView
。
我在上面阅读了文档here。
文档非常简短,并说:
"此属性通常用于将附件视图附加到为UITextField和UITextView对象显示的系统提供的键盘。
此只读属性的值为nil。如果要将自定义控件附加到系统提供的输入视图(例如系统键盘)或自定义输入视图(在inputView属性中提供的视图),请在UIResponder子类中将此属性重新声明为read-write。 / p>
然后,您可以使用此属性来管理自定义附件视图。当接收器成为第一响应者时,响应者基础设施将附件视图附加到适当的输入视图,然后再显示它。"
我尝试过声明属性
@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;
}
然后我试着调用这两个:
[self.tableView becomeFirstResponder];
[view becomeFirstResponder];
什么都没发生。我做错了什么?
*注意 - 额外信息:我使用UITableViewController
我希望将UIView
附加为inputAccessoryView
。一旦我查看了视图,我将添加UITextView
以及更多内容,但这主要是一个示例。
非常感谢任何帮助!
答案 0 :(得分:8)
将输入附件添加到textField或textView而不是纯UIView。
self.mytextField.inputAccessoryView = view;
答案 1 :(得分:1)
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]];
然后,每个字段都会有一个自定义附件视图,如this。
答案 2 :(得分:0)
删除self.inputAccessoryView = view;
,然后在-(void)viewDidLoad { ... }
是您的UIView的view
之后的以下任何位置添加代码:
-(void) viewDidLoad {
....
}
- (UIView *)inputAccessoryView
{
return self.view;
}
答案 3 :(得分:-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]];
我使工具栏的框架最初位于视图控制器的底部。
接下来,我只是在工具栏上启动我想要的其他对象,例如UITextField
和UIButton
。只要按照你想要的方式布置它们:
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
时,由于其inputAccessory查看toolbar
,toolbar
将停靠在键盘上!
由于我使用的是UITableViewController
,因此我必须将toolbar
添加到窗口中:
[[[UIApplication sharedApplication]delegate].window addSubview:toolbar];
这么简单!没有额外的课程或任何需要做的事情!