CALayer cornerRadius对4“设备(模拟器)没有影响

时间:2014-03-30 18:34:24

标签: objective-c iphone-5 cornerradius

我动态地,以编程方式为3.5“设备以及4”设备布局视图。 因此,工作正常。 但我想要圆角,以便我的图像看起来像扑克牌。 我在模拟器上的3,5英寸设备中可以很好地显示圆角,用于模拟iOS 6.1和7。 但是当我在6.1或7上选择iPhone视网膜4英寸时,UIImageView中的UIImage就会完全显示出来。 它适用于模拟的iPad设备(在iPhone模拟模式下 - 它是一个仅限iPhone的应用程序)。

至于今天,我没有任何4台设备可供我测试。我可以在即将到来的一周内在设备上进行测试。

Hiere是相关代码:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    self.imageV.image = self.image; // The image property was set by the caller.

    // Layout imageV within self.view with a margin of MARGIN
    self.imageV.frame = CGRectMake(self.view.frame.origin.x + MARGIN, self.view.frame.origin.y + MARGIN, self.view.frame.size.width - 2 * MARGIN, self.view.frame.size.height - 2 * MARGIN);

    // set the raidus and the mask to follow the rounded corners.
    self.imageV.layer.cornerRadius = CORNER_RADIUS;
    self.imageV.layer.masksToBounds = YES;
}

BTW:CORNER_RADIUS为18,MARGIN为15.更改这些值对此问题没有影响。

更新:感谢Matt我发现当我以编程方式创建UIImageView时问题就消失了。这是一些非常好的解决方法加上它指向正确的方向,我猜,但它不是一个解决方案。任何想法故事板编辑器中的设置可能导致问题? 据我所知,此故事板中的所有视图控制器都禁用了自动布局。

3.5" device 4" device

2 个答案:

答案 0 :(得分:2)

答案很简单。代码确实有效。它确实为UIImageView对象添加了圆角,并且maskToBounds运行良好。

但显示的实际图像较小。我使用AspectFit作为模式,以确保实际图像不会被挤压,而是以原始的纵横比显示。由于iPhone5尺寸的布局较长,因此图像仅填充了其拥有的UIImageView的一部分。我将屏幕截图的背景颜色更改为灰色,现在它变得清晰了。

因此,解决方案是我必须计算图像视图的正确大小,以使其与缩放图像的大小完全匹配。然后它应该工作。

(完成后我会更新此答案)。

enter image description here

更新:这是我最终做的:我从故事板中删除了UIImageView并以编程方式处理它。

不要对复杂性感到困惑。我添加了另一个视图只是为了抛出一个阴影,虽然这与原始问题无关。无论如何我想添加的影子。事实证明,CALayer的影子和masksToBounds=YES并不真正同意。这就是为什么我添加了一个位于卡片视图和背景视图之间的常规UIView。

最后,这对于显示一个简单的矩形图像来说是一件很麻烦的事情,我认为,只需将UIView子类化并使用openGL将所有内容直接绘制到CALayer中可能会容易得多。 :-)

无论如何,这是我的代码:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.state = @0;

    // Create an image view to carry the image with round rects
    // and create a regular view to create the shadow.
    // Add the shadow view first so that it appears behind
    // the actual image view.

    // Explanation: We need a separate view for the shadow with the same
    // dimenstions as the imageView. This is because the imageView's image
    // is rectangular and will only be clipped to round rects when the
    // property masksToBounds is set to YES. But this setting will also
    // clip away any shadow that the imageView's layer may have.
    // Therfore we add a separate mainly empty UIView just behind the
    // UIImageview to throw the shadow.


    self.shadowV = [[UIView alloc] init];
    self.imageV = [[UIImageView alloc] initWithImage:self.image];
    [self.view addSubview:self.shadowV];
    [self.shadowV addSubview:self.imageV];

    // set the raidus and the mask to follow the rounded corners.
    [self.imageV.layer setCornerRadius:CORNER_RADIUS];
    [self.imageV.layer setMasksToBounds:YES];
    [self.imageV setContentMode:UIViewContentModeScaleAspectFit];

    // set the shadows properties
    [self.shadowV.layer setShadowColor:[UIColor blackColor].CGColor];
    [self.shadowV.layer setShadowOpacity:0.4];
    [self.shadowV.layer setShadowRadius:3.0];
    [self.shadowV.layer setShadowOffset:CGSizeMake(SHADOW_OFFSET, SHADOW_OFFSET)];
    [self.shadowV.layer setCornerRadius:CORNER_RADIUS];
    [self.shadowV setBackgroundColor:[UIColor whiteColor]];   // The view needs to have some content. Otherwise it is not displayed at all, not even its shadow.

}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // Just to be save
    if (!self.image) {
        return;
    }

    self.imageV.image = self.image; // The image property was set by the caller.

    // Layout imageV within self.view with a margin of MARGIN
    self.imageV.frame = CGRectMake(MARGIN, MARGIN, self.view.bounds.size.width - 2 * MARGIN, self.view.bounds.size.height - 2 * MARGIN);


    // Calculate the size and position of the image and set the image view to
    // the same dimensions
    // This works under the assumption, that the image content mode is aspectFit.
    // Well, as we are doing so much of the layout manually, it would work with a number of content modes. :-)

    float imageWidth, imageHeight;
    float heightWidthRatioImageView     = self.view.frame.size.height / self.view.frame.size.width;
    float heightWidthRatioImage         = self.image.size.height / self.image.size.width;

    if (heightWidthRatioImageView > heightWidthRatioImage) {
        // The ImageView is "higher" than the image itself.
        // --> The image width is set to the imageView width and its height is scaled accordingly.
        imageWidth  = self.imageV.frame.size.width;
        imageHeight = imageWidth * heightWidthRatioImage;
    } else {
        // The ImageView is "wider" than the image itself.
        // --> The image height is set to the imageView height and its width is scaled accordingly.
        imageHeight = self.imageV.frame.size.height;
        imageWidth  = imageHeight / heightWidthRatioImage;
    }

    // Layout imageView and ShadowView accordingly.
    CGRect imageRect =CGRectMake((self.view.bounds.size.width - imageWidth) / 2,
                                 (self.view.bounds.size.height - imageHeight) / 2,
                                 imageWidth, imageHeight);
    [self.shadowV setFrame:imageRect];
    [self.imageV setFrame:CGRectMake(0.0f, 0.0f, imageWidth, imageHeight)]; // Origin is (0,0) because it overlaps its superview which just throws the shadow.

}

这就是它最终的样子: enter image description here enter image description here

答案 1 :(得分:1)

问题是由于您没有告诉我们的代码或配置的某些问题。证明:我运行以下内容并且工作正常。请注意,我在代码中创建了图像视图(以避免自动布局问题)并修复了帧/边界的混乱,并且我已经跳过了self.image,但这些都与您的问题无关看到:

#define CORNER_RADIUS 18
#define MARGIN 15
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.imageV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"im"]];
    [self.view addSubview:self.imageV];
    // Layout imageV within self.view with a margin of MARGIN
    self.imageV.frame = CGRectMake(self.view.bounds.origin.x + MARGIN, self.view.bounds.origin.y + MARGIN, self.view.bounds.size.width - 2 * MARGIN, self.view.bounds.size.height - 2 * MARGIN);
    // set the raidus and the mask to follow the rounded corners.
    self.imageV.layer.cornerRadius = CORNER_RADIUS;
    self.imageV.layer.masksToBounds = YES;
}

它工作正常(你可以向自己证明)。这是4英寸模拟器的屏幕截图:

enter image description here

因此,问题超出了您在问题中引用的代码,如果没有进一步的信息,则无法进行分析。