使用UIModalPresentationFormSheet将父视图显示为模式时,UITableViewCell框架会发生更改

时间:2012-02-19 01:37:40

标签: ios ipad uitableview modal-dialog

代码状态:

我正在为表格视图中的表单编写自己的库(我知道Sensible Cocoa但愿意自己写)并且我正在处理与它松散连接的问题。

我的表单由UITableViewController以UITableViewStyleGrouped样式保存。这个表视图控制器是在一个按钮处理程序中使用此代码创建的(ommited表单模型的初始化):

// prepare table view model
_formTableViewController = [[ESCTableViewController alloc] initWithModel:model];
_formTableViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 
                                                                                                      target:self action:@selector(cancelBarButtonItemHandler:)];
_formTableViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit 
                                                                                                           target:self action:@selector(editBarButtonItemHandler:)]; 
// prepare navigation controller containing the tableViewController
ESCNavigationController *navigationController = [[ESCNavigationController alloc] initWithRootViewController:_formTableViewController];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;

// present navigation view controller
[self presentViewController:navigationController animated:YES completion:nil];

然后,我有UITableViewCell子类(如ESCTableViewCell),其样式为UITableViewCellStyleDefault,每个表单组件都是ESCTableViewCell的后代,使用其基本初始化程序和少量属性。

我正在进行这样的自定义渲染:

  1. 在特定单元格的初始化程序(ESCTextFieldCell)中创建自定义字段(即UITextField)
  2. prepareForReuse由细胞重用框架调用,我删除旧的观察者并使无效的内容无效
  3. configWithModel :( Model *)模型,我在其中设置单元格的属性,添加观察者等。
  4. layoutSubviews由框架调用;这个过程的元代码在这里:

    CGFloat const ESCTextFieldWidthRatio = 0.65f;
    CGFloat const ESCFieldHeight = 22.0f;
    CGFloat const ESCFieldPadding = 10.0f;
    
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];
    
    // call super layout subviews first
    [super layoutSubviews];
    
    // count width of the text field, so it would fit with label
    // must round() the results to avoid antialiasing on fractional values
    CGFloat contentWidth = self.contentView.frame.size.width;
    CGFloat contentHeight = self.contentView.frame.size.height;
    CGFloat fieldWidth = round((contentWidth - (2 * ESCFieldPadding)) * ESCTextFieldWidthRatio);
    CGFloat fieldOriginY = round((contentHeight / 2) - (ESCFieldHeight / 2));
    CGFloat labelWidth = contentWidth - fieldWidth - (4 * ESCFieldPadding);
    
    // set textlabel and textfield frames
    self.textLabel.frame = CGRectMake(ESCFieldPadding, 0.0f, labelWidth, contentHeight);
    self.textField.frame = CGRectMake(labelWidth + (3 * ESCFieldPadding), fieldOriginY, fieldWidth, ESCFieldHeight);
    
    [UIView commitAnimations];
    
  5. 问题:

    我试图让UI尽可能干净,成为一个完美主义者;因此,我希望在编辑模式的进入/离开时对表视图单元格进行动画处理,这在当前的代码状态下运行良好。

    问题在于使用此表格视图内部呈现模态视图本身。似乎(通过模拟器证明 - 慢动画),在呈现模态视图时,表视图的帧被(至少)几个像素更新(缩小),这导致模态视图转换动画和表视图单元格调整大小动画,最后导致该模态视图演示的动画不那么平滑。

    我想了解的是,为什么表视图单元格正在调整模态视图的显示,因为我不喜欢在呈现模态视图时破解代码禁用动画的想法(它可能导致以后还有很多其他问题。)

    拜托,有人知道为什么会这样,或者你有其他想法如何以非黑客的方式覆盖它?

    非常感谢你!

    PS:我正在使用ARC,但我认为这不重要。

    PS2:iPad5和iOS模拟器上的问题都出现在iOS5上。

3 个答案:

答案 0 :(得分:0)

米罗斯拉夫,我不确定这有什么帮助,但我一直在打同样的事情。我在这里分享这个,因为我认为其他人可能想知道发生了什么。

这不仅仅是单元格,它是整个tableview边界,直到调用ViewDidAppear才能解决。

因此,假设您想要使用UITableViewController调出500x500模式,使用presentViewController启动它,您将进行各种调整,直到它最终在ViewDidAppear中解析。在我的情况下,我通过调试看到它从1024宽到320然后最终到500.而且我需要确定表视图单元格的最终高度。

在这种情况下,这一切似乎都是黑客攻击,但我不确定是否有一个干净的解决方案,尽管我希望有一个。我现在正在测试它的一种方法是,在layoutSubviews中调整大小时,自定义表格视图单元格具有“最终宽度”属性(如果已设置)。这样,可以在tableview成为最终形式之前的任何时间计算单元格的正确高度(基于此固定宽度)。

答案 1 :(得分:0)

我在iOS上的一些原创(阅读Apple)应用程序中看到了同样的问题,所以我认为它是该系统的一个特性。看来,我们能做的最好的事情就是尽可能地隐藏它。实际上,除了我之外没有人注意到这种行为,所以我认为没有人会受到打扰。

认为它不是答案,而是封闭。如果你有一些真正的问题解决方案,请在这里写下来,我会把它标记为答案。

答案 2 :(得分:0)

UITableView布局设置为在自动调整大小之外删除。

enter image description here