0

我有一个带有 3 个视图的 viewController:topView、tableView 和 textView。

我希望他们像这样布局:

在纵向模式下 -

|---------------|  
|    topView    |  
|---------------|
|               |
|               |
|   tableView   |
|               |
|               |
|---------------|               
|   textView    |
|---------------|

在横向模式下:

|--------------------------|  
|         topView          |  
|--------------------------|
|                          |
|        tableView         |
|--------------------------|               
|        textView          |
|--------------------------|

当键盘启动时:

|---------------|  
|               |
|   tableView   |
|               |
|---------------|               
|   textView    |
|---------------|  
|               |
|   keyboard    |
|               | 
|---------------|  

|--------------------------|  
|        tableView         |
|--------------------------|               
|        textView          |
|--------------------------| 
|                          |
|        keyboard          |
|--------------------------|  

(如您所见,当键盘启动时,顶视图消失了)

这样做的代码是:

- (void)loadView
{
    [super loadView];

    // load top view
    _topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, TOP_VIEW_HEIGHT)];
    _topView.autoresizingMask =  UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;
    _topView.backgroundColor = [UIColor redColor];
    [self.view addSubview:_topView];

    // load table view (at the middle)
    CGRect tableFrame = CGRectMake(0, TOP_VIEW_HEIGHT, self.view.bounds.size.width, self.view.bounds.size.height - TOP_VIEW_HEIGHT - TEXT_VIEW_HEIGHT);
    _tableView = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStylePlain];
    _tableView.autoresizingMask =  UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    _tableView.delegate = self;
    _tableView.dataSource = self;
    [self.view addSubview:_tableView];

    // load text view (at the bottom)
    CGRect textViewFrame = CGRectMake(0, tableFrame.size.height + TOP_VIEW_HEIGHT, self.view.bounds.size.width, TEXT_VIEW_HEIGHT);
    _textView = [[UITextView alloc] initWithFrame:textViewFrame];
    _textView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
    _textView.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:_textView];
}  



- (void)keyboardWillShow:(NSNotification *)notification 
{
    NSDictionary *userInfo = [notification userInfo];

    // Get animation info from userInfo
    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;


    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];

    CGSize kbSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    CGRect textViewFrame = self.textView.frame;
    textViewFrame.origin.y -= kbSize.height;

    CGRect topViewFrame = self.topView.frame;
    topViewFrame.origin.y -= topViewFrame.size.height;

    CGRect tableFrame = self.tableView.frame;
    tableFrame.origin.y -= topViewFrame.size.height;
    tableFrame.size.height -= (kbSize.height - topViewFrame.size.height);

    [UIView animateWithDuration:animationDuration delay:0.0 options:animationCurve animations:^{
        self.textView.frame = textViewFrame;
        self.tableView.frame = tableFrame;
        self.topView.frame = topViewFrame;
    }completion:^(BOOL finished) {

    }];
}

- (void)keyboardWillHide:(NSNotification *)notification 
{
    NSDictionary *userInfo = [notification userInfo];

    // Get animation info from userInfo
    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;


    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];

    CGSize kbSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    CGRect textViewFrame = self.textView.frame;
    textViewFrame.origin.y += kbSize.height;

    CGRect topViewFrame = self.topView.frame;
    topViewFrame.origin.y += topViewFrame.size.height;

    CGRect tableFrame = self.tableView.frame;
    tableFrame.origin.y += topViewFrame.size.height;
    tableFrame.size.height += kbSize.height - topViewFrame.size.height;

    [UIView animateWithDuration:animationDuration delay:0.0 options:animationCurve animations:^{
        self.textView.frame = textViewFrame;
        self.tableView.frame = tableFrame;
        self.topView.frame = topViewFrame;
    }completion:^(BOOL finished) {
        //
    }];
}

我想要的大部分工作都很好,问题是当键盘以横向模式显示时,事情就会出错..

请注意viewsautoresizingMask属性,因为我不确定我当前是否设置了它。

4

2 回答 2

1

我发现了问题,当我在keyboardWillShow/willHide 中执行视图的向上/向下动画时,我没有将键盘矩形从屏幕转换为视图坐标

CGRect kbRect = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
kbRect = [self.view convertRect:kbRect fromView:nil];
CGSize kbSize = kbRect.size; 

现在它工作正常:)

于 2012-06-06T21:37:34.473 回答
1

对于自动旋转,尝试将顶视图的遮罩设置为灵活宽度,中间的遮罩设置为灵活宽度和灵活高度,以及文本视图、灵活宽度和上边距。我怀疑这会顺利进行,但值得一试。您可以覆盖willAnimateRotationToInterfaceOrientation:duration:视图控制器以进行自定义工作。我很确定基本的自动旋转蒙版无法处理这种布局,但我很想被证明是错误的。

还要像这样检查方向loadView

if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
    // do one layout
} else {
    // do another layout
}

我也在我的应用程序中做非常自定义的旋转工作(想想从头开始的自定义拆分视图控制器 - 恶心),我正在使用willAutorotateand UIInterfaceOrientationIsLandscape.

由于您提出问题的方式,这可能不适用于您:我不确定问题是否在于您打开键盘,然后旋转到横向(在这种情况下,此答案可能会有所帮助);或者您在横向打开键盘时是否有问题(在这种情况下,这个答案可能与您不太相关)。

于 2012-06-06T21:14:45.337 回答