为什么iOS自动布局导致Pre-Retina显示屏之前出现明显的舍入误差(包括单元测试)

为什么iOS自动布局导致Pre-Retina显示屏之前出现明显的舍入误差(包括单元测试),第1张

概述我目前很难理解为什么以下单元测试在iPad 2上失败.自动布局似乎略微(0.5分)在超视图内部的错位置视图相对于两个布局约束所要求的精确对中.似乎特别奇怪的是,关键的测试(但最后的断言)通过iPhone 5,所以明显的舍入误差仅影响一个(iOS 6)平台.这里发生了什么? 更新1我已经改变了代码,以确保两个框架在宽度和高度方面都受到足够的约束,即使转换为AutotoresizingMaskInto 我目前很难理解为什么以下单元测试在iPad 2上失败.自动布局似乎略微(0.5分)在超视图内部的错位置视图相对于两个布局约束所要求的精确对中.似乎特别奇怪的是,关键的测试(但最后的断言)通过iPhone 5,所以明显的舍入误差仅影响一个(iOS 6)平台.这里发生了什么?

更新1我已经改变了代码,以确保两个框架在宽度和高度方面都受到足够的约束,即使转换为autotoresizingMaskIntoConstraints为NO,建议作为可能的相关补救措施here.但是,这显然不会改变这种情况.

#import "BUGTests.h"@implementation BUGTests- (voID)testCenteredLayout {    UIVIEw *supervIEw = [[UIVIEw alloc] initWithFrame:CGRectMake(0,768,88)];    supervIEw.autoresizingMask = UIVIEwautoresizingFlexibletopmargin | UIVIEwautoresizingFlexibleBottommargin;    supervIEw.translatesautoresizingMaskIntoConstraints = YES;    UILabel *vIEw = [[UILabel alloc] initWithFrame:CGRectMake(0,0)];    vIEw.text = @"Single Round against iPad.";    vIEw.autoresizingMask = UIVIEwautoresizingFlexibletopmargin | UIVIEwautoresizingFlexibleBottommargin;    vIEw.translatesautoresizingMaskIntoConstraints = NO;    [vIEw addConstraint:[NSLayoutConstraint constraintWithItem:vIEw attribute:NSLayoutAttributeWIDth  relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplIEr:0.0 constant:206.0]];    [vIEw addConstraint:[NSLayoutConstraint constraintWithItem:vIEw attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplIEr:0.0 constant: 21.0]];    [supervIEw addSubvIEw:vIEw];    [supervIEw addConstraint:[NSLayoutConstraint constraintWithItem:supervIEw attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:vIEw attribute:NSLayoutAttributeCenterX multiplIEr:1.0 constant:0.0]];    [supervIEw addConstraint:[NSLayoutConstraint constraintWithItem:supervIEw attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:vIEw attribute:NSLayoutAttributeCenterY multiplIEr:1.0 constant:0.0]];    STAssertEquals(supervIEw.center,CGPointMake(384,44),nil); // succeeds    STAssertEquals(vIEw.center,CGPointMake(  0,0),nil); // succeeds    [supervIEw setNeedsLayout];    [supervIEw layoutIfNeeded];    STAssertTrue(!supervIEw.hasAmbiguousLayout,nil);    STAssertEquals(supervIEw.frame.size,CGSizeMake(768,88),nil); // succeeds    STAssertEquals(vIEw.frame.size,CGSizeMake(206,21),nil); // succeeds    STAssertEquals(supervIEw.center,vIEw.center,nil); // fails: why?    STAssertEquals(vIEw.center,44.5),nil); // succeeds: why?}@end

更新2我在另一个单元测试中孤立了另一个(显然)同一个问题的实例.这一次它涉及顶部(而不是中心)的约束,而这次分数点坐标似乎是触发器. (测试也可以在Retina设备上成功,例如y = 951,即一个奇点坐标).我已经检查了各种模拟器配置(我的物理iPad 2和iPhone 5旁边)的确发生似乎与没有一个Ratina显示. (再次感谢@ArkadiuszHolko领先.)

我目前从这些测试的感觉是,如果需要在Retina显示器上进行点精确自动布局,则必须避免奇异的高度和小数y坐标.但为什么?

- (voID)testNonRetinaautoLayoutProblem2 {    UIVIEw *supervIEw = [[UIVIEw alloc] initWithFrame:CGRectMake(0,1004)];    supervIEw.autoresizingMask = UIVIEwautoresizingFlexibleRightmargin | UIVIEwautoresizingFlexibleBottommargin;    supervIEw.translatesautoresizingMaskIntoConstraints = YES;    CGfloat y = 950.5; // see e.g. pageControltopConstraint    UIVIEw *vIEw = [[UIVIEw alloc] initWithFrame:CGRectMake(0,0)];    vIEw.translatesautoresizingMaskIntoConstraints = NO;    [supervIEw addConstraint:[NSLayoutConstraint constraintWithItem:vIEw attribute:NSLayoutAttributeLeading  relatedBy:NSLayoutRelationEqual toItem:supervIEw attribute:NSLayoutAttributeLeading        multiplIEr:1.0 constant:0.0]];    [supervIEw addConstraint:[NSLayoutConstraint constraintWithItem:vIEw attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:supervIEw attribute:NSLayoutAttributeTrailing       multiplIEr:1.0 constant:0.0]];    [supervIEw addConstraint:[NSLayoutConstraint constraintWithItem:vIEw attribute:NSLayoutAttributetop      relatedBy:NSLayoutRelationEqual toItem:supervIEw attribute:NSLayoutAttributetop            multiplIEr:1.0 constant:y]];    [supervIEw addConstraint:[NSLayoutConstraint constraintWithItem:vIEw attribute:NSLayoutAttributeHeight   relatedBy:NSLayoutRelationEqual toItem:nil       attribute:NSLayoutAttributeNotAnAttribute multiplIEr:0.0 constant:8]];    [supervIEw addSubvIEw:vIEw];    [supervIEw setNeedsLayout];    [supervIEw layoutIfNeeded];    STAssertTrue(!supervIEw.hasAmbiguousLayout,nil);    STAssertTrue(!vIEw.hasAmbiguousLayout,nil);    STAssertEquals(supervIEw.frame,CGRectMake(0,1004),nil); // succeeds    STAssertEquals(vIEw.frame,y,8),nil); // fails: why?    STAssertEquals(vIEw.frame,y + 0.5,nil); // succeeds: why?}
解决方法 你所看到的是,自动布局憎恶不一致的观点.在非视网膜设备上,最接近的像素是最接近的点,因此它会舍入到整数.在视网膜屏幕上,最接近的像素是最接近的半点,所以它最接近最接近的0.5.您可以通过将第二个测试中的y更改为950.25,并注意到vIEw.frame保留{{0,95.5},{768,8}}(而不是更改为{{0,95.25}} {768,8}} }).

(只是为了证明它是四舍五入而不是天花板,如果你将y更改为950.2 vIEw.frame成为{{0,950} {{{8},8}}}.

总结

以上是内存溢出为你收集整理的为什么iOS自动布局导致Pre-Retina显示屏之前出现明显的舍入误差(包括单元测试)全部内容,希望文章能够帮你解决为什么iOS自动布局导致Pre-Retina显示屏之前出现明显的舍入误差(包括单元测试)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1110486.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存