Ios NSLAYOUTSCONSTRAINT和设置视图纵向上X像素和横向上Y像素

Ios NSLAYOUTSCONSTRAINT和设置视图纵向上X像素和横向上Y像素,ios,objective-c,nslayoutconstraint,Ios,Objective C,Nslayoutconstraint,希望表格视图在纵向显示时从顶部向下显示300像素,在横向显示时从顶部向下显示约175像素 我似乎无法理解我所需要的VFL逻辑。我认为无论如何,如果不在旋转回调方法的代码中对其进行更改,就无法将其设置为执行特定的距离。如果在IB中为约束创建一个IBOutlet(我们称之为con1),并使该约束的初始值为300,那么在旋转回调方法中,您可以只更改该常量 self.con1.常数=175 编辑后: 这项工作: - (void)willRotateToInterfaceOrientation:(UIIn

希望表格视图在纵向显示时从顶部向下显示300像素,在横向显示时从顶部向下显示约175像素


我似乎无法理解我所需要的VFL逻辑。

我认为无论如何,如果不在旋转回调方法的代码中对其进行更改,就无法将其设置为执行特定的距离。如果在IB中为约束创建一个IBOutlet(我们称之为con1),并使该约束的初始值为300,那么在旋转回调方法中,您可以只更改该常量

self.con1.常数=175

编辑后:

这项工作:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

    if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        con1.constant = 175;
    }else{
        con1.constant = 300;
    }
}

像许多自动布局问题一样,是的,你可以按你的要求去做,但这远不是显而易见的。如果我真的需要精确的300pt或175pt,我可能也会尝试调整旋转的顶部约束

但是,如果您想知道如何在不处理旋转事件的情况下执行此操作,您可以:

  • 将所需的最小上边距设置为175

  • 设置较低优先级的首选顶部边距300(在景观中不满足此要求);及

  • 不太明显的是,您还需要一个所需的最小高度(这样,在横向中,它将知道不满足较低优先级的请求以使顶部边距为300)

  • 例如,您可以使用(显然,用对您有意义的任何内容替换我的底部边距5,但相应地调整tableview的最小高度):

    结合:

    @"V:|-(300@500)-[tableView]"
    
    (显然,水平轴也有约束,但为了简洁起见,我省略了这些约束。)

    不可否认,必须精确地指定最小表格高度也有点不吸引人,但我认为没有其他方法可以告诉autolayout在什么情况下应该优雅地不满足300pt的可选顶部空间


    您还可以使用
    constraintWithItem
    的y=mx+b公式来实现这一点。是的,我知道您问过如何使用Visual Format Language实现这一点,但是如果您使用
    constraintWithItem
    ,您不必指定最小表格高度,而是可以像这样设置顶部边距:

    constraint = [NSLayoutConstraint constraintWithItem:self.tableView
                                              attribute:NSLayoutAttributeTop
                                              relatedBy:NSLayoutRelationEqual
                                                 toItem:self.tableView.superview
                                              attribute:NSLayoutAttributeBottom
                                             multiplier:multiplier
                                               constant:constant];
    
    很明显,诀窍在于如何确定
    乘数
    常数
    ,这样你在纵向得到300磅,在横向得到175磅。做一点代数,你会发现你可以计算这些值,如下所示:

    CGFloat multiplier = (300.0 - 175.0) / (superviewPortraitHeight - superviewLandscapeHeight);
    CGFloat constant = 175.0 - superviewLandscapeHeight * multiplier;
    

    (同样,我会假设您将指定其他约束,以便tableview的定义不会含糊不清,例如,设置左、右和底部约束,这可以用可视化格式语言完成。)

    @Log139,我认为您可以通过这种方式将其移近顶部,但我不知道您是否可以得到确切的数字(175)。如果对顶部和底部都有约束,并为顶部设置较低的优先级,则旋转时将保持较高的优先级距离(到底部),并使到顶部的距离变小。如果你视野的高度正好,那么距离可能是175。我也有同样的想法,但我不确定如何建立逻辑。不完全是175,但很接近。类似于V:|-(=500@750)-|? 那么顶部最多是300像素,底部则大于500像素?如果它大于500像素,它将是纵向的,而在lanscape中则是较小的…@Log139,我认为这可能会给你一个模棱两可的情况,此外,如果你必须用代码来做,那么我在回答中所说的方式会更简单,并且会给你你想要的确切数字。太棒了,constraintWithItem工作得很完美。它有一定的意义,应该能够在其他地方使用它,我需要做同样的事情。我想我想用约束来做这件事,因为据我所知,约束应该取代使用旋转方向委托的需要(就像rdelmar建议的那样)?@Log139是的,从长远来看,苹果希望开发者关注超级视图的
    边界
    ,而不是设备的方向。但我有一部分怀疑autolayout是否真的为黄金时间做好了准备。太复杂了。VFL有一些明显的缺陷。自动布局的灵活性与设备和特定于方向的数字资产之间也存在认知上的不协调。我向你致敬,感谢你的热情,但对我来说,陪审团还没有出来。就我个人而言,我不太愿意宣布上述代码是对传统方法的改进。它不应该是
    @“V:|-(>=175)-[tableView(>=120)]-5-|”
    ?@AlexsanderAkers是的,我相信是这样。抢手货谢谢
    CGFloat multiplier = (300.0 - 175.0) / (superviewPortraitHeight - superviewLandscapeHeight);
    CGFloat constant = 175.0 - superviewLandscapeHeight * multiplier;