Offset UITableView Content When Keyboard Appears

本文介绍如何在iOS应用中通过监听键盘通知来调整UITableView或UITextView的内容偏移,确保键盘弹出时内容不会被遮挡。文章提供了具体的实现代码,包括注册键盘通知、调整内容偏移及恢复原始位置的方法。

This post will show how to adjust the content insets of a uitableview or uitextview when the keyboard pops up, so nothing is hidden underneath. I’m just going to jump right into the code for this one because this post is more for reference whenever this topic comes up. I’m not going to do a full tutorial for something like this.

The way we will accomplish this is by first registering for keyboard notifications, then adjusting the content inset based on the height of the keyboard.

Register for notifications

In your viewDidLoad or viewWillAppear method add the code to register for keyboard notifications.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}

We add this view controller as the observer. We pass in the selector of the method that should be called when this notification occurs, which we will write in a minute. Having the colon at the end of the selector is important because this tells it that it should pass the notification parameter to the method. Then we give the name of the notification we want to observe, UIKeyboardWillShowNotification and UIKeyboardWillHideNotification, which are predefined notifications. The object parameter is asking us to define which object will post this notification, which according to the documentation should be nil for the keyboard notifications.

Wherever you register for these notifications, you should unregister as an observer in the opposing method (viewDidAppear vs viewDidDisappear). So, if you put them in viewDidLoad, you can unregister in dealloc sinceviewDidUnload is deprecated.

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

This line simply removes this view controller as an observer of all notifications. Be sure not to call [super dealloc] now with ARC.

Apply the content insets

Now we need to write the keyboardWillShow: method we registered as the selector to call.

- (void)keyboardWillShow:(NSNotification *)notification
{    
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets;
    if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])) {
        contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.height), 0.0);
    } else {
        contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.width), 0.0);
    }

    self.tableView.contentInset = contentInsets;
    self.tableView.scrollIndicatorInsets = contentInsets;
    [self.tableView scrollToRowAtIndexPath:self.editingIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

To get the keyboard size, we first get the userInfo dictionary from the notification object, which stores any additional objects that our receiver might use. From that dictionary we can get the CGRect object describing the keyboard’s frame by using the key UIKeyboardFrameBeginUserInfoKey. Then we get the CGSize value from that CGRect.

The coordinates given to us do not take into account rotation, so we need to check if the app is in portrait or landscape mode. If we are in portrait we create a UIEdgeInsets object with the height of the keyboard. If in landscape we use the width since this is actually the height.

Next we apply the content inset to the tableview, or this could be a textview, scrollview, etc. This way is better than trying to change the frame of the view around to adjust. The tableview will stay in the same position, but it will move all of its content up above the keyboard.

Rotation is also handled this way because the UIKeyboardWillShowNotification is posted on an orientation change if the keyboard is open.

Restore original position

Now we just have to reset the inset when the keyboard hides.

- (void)keyboardWillHide:(NSNotification *)notification
{
    self.tableView.contentInset = UIEdgeInsetsZero;
    self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero;
}

As pointed out by Alaeddine in the comments, you might want to wrap the setting of the insets in an animation. The usual keyboard animation rate seems to be 0.3 seconds, but it could be different based on region, such as when international users switch between keyboard sizes. The best way to get the duration of the animation is to grab it from the userInfo dictionary that comes in the keyboard notification. Be sure to make the change in both keyboardWillShow: andkeyboardWillHide:. The change that needs to be made is as follows…

NSNumber *rate = notification.userInfo[UIKeyboardAnimationDurationUserInfoKey];
[UIView animateWithDuration:rate.floatValue animations:^{
        self.tableView.contentInset = // insert content inset value here
        self.tableView.scrollIndicatorInsets = // insert content inset value here
}];
乐播投屏是一款简单好用、功能强大的专业投屏软件,支持手机投屏电视、手机投电脑、电脑投电视等多种投屏方式。 多端兼容与跨网投屏:支持手机、平板、电脑等多种设备之间的自由组合投屏,且无需连接 WiFi,通过跨屏技术打破网络限制,扫一扫即可投屏。 广泛的应用支持:支持 10000+APP 投屏,包括综合视频、网盘与浏览器、美韩剧、斗鱼、虎牙等直播平台,还能将央视、湖南卫视等各大卫视的直播内容一键投屏。 高清流畅投屏体验:腾讯独家智能音画调校技术,支持 4K 高清画质、240Hz 超高帧率,低延迟不卡顿,能为用户提供更高清、流畅的视觉享受。 会议办公功能强大:拥有全球唯一的 “超级投屏空间”,扫码即投,无需安装。支持多人共享投屏、远程协作批注,PPT、Excel、视频等文件都能流畅展示,还具备企业级安全加密,保障会议资料不泄露。 多人互动功能:支持多人投屏,邀请好友加入投屏互动,远程也可加入。同时具备一屏多显、语音互动功能,支持多人连麦,实时语音交流。 文件支持全面:支持 PPT、PDF、Word、Excel 等办公文件,以及视频、图片等多种类型文件的投屏,还支持网盘直投,无需下载和转格式。 特色功能丰富:投屏时可同步录制投屏画面,部分版本还支持通过触控屏或电视端外接鼠标反控电脑,以及在投屏过程中用画笔实时标注等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值