在 Xcode 中使用自动布局禁用了我的代码(动态)工作?

Posted

技术标签:

【中文标题】在 Xcode 中使用自动布局禁用了我的代码(动态)工作?【英文标题】:Using AutoLayout in Xcode disables my code from working (dynamically)? 【发布时间】:2013-02-07 19:11:17 【问题描述】:

在我的项目中,我启用了 AutoLayout 以使应用程序在 iPhone 4 和 iPhone 5 中都能正常缩放。这样做一切正常,但我发现了一个新问题,我不确定如何处理。

在我的项目中,我有一个普通的方法来检查布尔值是或否,如果是,界面应该在界面中添加一个按钮并将我的 tableView 保持在当前状态。但是如果该方法返回 no,按钮应该消失并使 tableView 的高度更高!按钮的一切工作正常,但由于某种原因,在开始使用 AutoLayout 后,我​​增加 tableView 高度的代码停止工作(之前工作)。

现在,即使我使用 AutoLayout,我该怎么做才能使我的 tableView 的高度增加?这是我的代码:

- (void)viewWillAppear:(BOOL)animated

NSString *bookName = [self getCurrentBookName];

if([self isBlank:bookName])

    [self.currentBookLabel setText:NSLocalizedString(@"LabelNoBookChosen", nil)];

else

    [self.currentBookLabel setText:[self getCurrentBookName]];


[super viewWillAppear:animated];

  if([self isAppLicensed] != YES)   <------------------THIS IS WHERE I CHECK THE BOOLEAN METHOD!

    [actionAppStore setHidden:TRUE];

    CGRect framez =  [tableView frame]; <------------------ THIS CODE IS NOT WORKING ANY LONGER!
    [tableView setFrame:CGRectMake(framez.origin.x, framez.origin.y, framez.size.width, framez.size.height+77)];
    
else

    [actionAppStore setHidden:FALSE];


【问题讨论】:

通过在以下方法中添加代码解决了它- (void)viewDidLayoutSubviews if([self isAppLicensed] != YES) [actionAppStore setHidden:TRUE]; CGRect framez = [tableView 框架]; [tableView setFrame:CGRectMake(framez.origin.x, framez.origin.y, framez.size.width, framez.size.height+77)]; else [actionAppStore setHidden:FALSE]; 这可能已经解决了您的问题,但这不是您应该使用布局约束的方式。如果您观看 Apple 关于该主题的开发者视频,您会发现您应该摆脱所有 setFrame: 消息。 【参考方案1】:

你可以

    关闭自动布局并使用自动调整大小的蒙版。非自动布局自动调整大小蒙版让您可以控制增加或减少 3.5 英寸屏幕与 4 英寸屏幕的控件大小。这可能是最简单的解决方案。它还让您与 ios 5 设备兼容。

    如果您想使用自动布局,那么您应该为适当的约束创建一个IBOutlet,然后以编程方式对其进行更改。


在后一个示例中,考虑一个布局,其中我在应用商店底部有一个表格视图和一个控件(我从您的变量名称中推断出这一点)。有两种方法可以隐藏和显示底部控件。一种是隐藏它(或将其alpha 设置为零或removeFromSuperview),删除不必要的约束,并重新创建新的适当约束。

这行得通,但很麻烦。我现在更喜欢将我想要隐藏的内容的高度更改为零,或者,如果它已经在屏幕边缘,我将它从边缘滑出,这样你就看不到它了。

因此,我可能会在视觉上隐藏应用商店控件,而不是通过玩弄它的 hidden 属性,而是通过将其高度更改为零(或者,为了显示它,更改为 77)。这样,其他约束将自动调整其他控件的大小。因此,我将其隐藏:

        self.appStoreHeightConstraint.constant = 0.0;
        [self.view layoutIfNeeded];

我显示:

        self.appStoreHeightConstraint.constant = 77.0;
        [self.view layoutIfNeeded];

我使用一个名为 appStoreHeightConstraintIBOutlet 来做到这一点,它与底部控件的高度约束相关联。

或者(并且仅当被隐藏的项目位于底部时),我可以将其滑出屏幕底部(这次在底部约束上使用IBOutlet),使用:

        self.appStoreBottomConstraint.constant = 77.0;
        [self.view layoutIfNeeded];

并显示它

        self.appStoreBottomConstraint.constant = 0.0;
        [self.view layoutIfNeeded];

为了全面披露,我应该提一下,您必须非常小心地设计约束,以便它们同时 (a) 最低限度地描述您的布局;但是 (b) 充分描述您的布局。您想避免可怕的冲突或不令人满意的约束消息。

只关注垂直维度,这意味着有以下约束:

表视图的顶部约束位于父视图的顶部; 表格视图的底部约束位于应用商店视图的顶部; table view 应该有 no 高度限制(因为这是你想要改变的,因为其他东西改变了); 底部的应用商店控件将其顶部约束链接到 tableview; 应用商店的底部约束链接到superview的底部;和 应用商店的高度限制固定为 77.0。

但我发现 IB 总是(真诚地努力确保约束是明确的)正在尝试添加额外的约束(例如 tableview 的高度)。所以,我个人与 IB 搏斗以使约束完全正确(通常我最终会降低 table view 高度的优先级,当我完成其他所有事情时,我可以回去摆脱 table view 高度) .

也许我在编辑约束时太麻烦了,但我提到它是因为如果你没有把它们都完全正确,通过改变一个约束来影响 UI 更改的努力不会产生你想要的结果.一旦你掌握了它的窍门,就很容易看到一切都相应地调整(尤其是在复杂的场景中),这是一件很美的事情。但前几次可能会很麻烦。

【讨论】:

【参考方案2】:

您可能需要告诉视图使用layoutIfNeeded 来布局其子视图。

请参阅 my question I just solved 和 this question is also related。

【讨论】:

感谢链接,其中一个解决了它并告诉我方法 - (void)viewDidLayoutSubviews。干杯!

以上是关于在 Xcode 中使用自动布局禁用了我的代码(动态)工作?的主要内容,如果未能解决你的问题,请参考以下文章

xcode自动布局问题

Xcode 6 中已开发应用程序中的自动布局实现

禁用单个 UIImageView 的自动布局

UITableViewCell 子类布局在禁用自动布局的故事板中搞砸了

修改已经使用自动布局布局的情节提要

Firebase 通用链接已禁用且无法正常工作 (iOS)