1

I am trying to load a profile image for an app, but I want to add a white border to it and make it circular before I display it. In order to do that I set the image property on the UIImageView and then prepare the image by setting the appropriate corner radius, masking it to the bounds and then adding a white border sublayer. Originally, I was loading the image in over the internet asynchronously and everything worked fine because the image appeared after the view had appeared. However, when I cached the image and tried to prepare it before the imageView was shown on screen I couldn't get the border sublayer to display. It still masked properly, just no border. The code that I am using to prepare the image is below.

- (void)prepareProfileImage
{
    CALayer *imageLayer = self.profileImageView.layer;
    imageLayer.borderColor = [UIColor whiteColor].CGColor;
    imageLayer.allowsEdgeAntialiasing = NO;
    [imageLayer setCornerRadius:PROFILE_IMAGE_DIAMETER/2.0];
    [imageLayer setMasksToBounds:YES];

    CALayer *borderLayer = [CALayer layer];
    CGRect borderFrame = CGRectMake(-1.0, -1.0, (self.profileImageView.frame.size.width+2.0), (self.profileImageView.frame.size.height+2.0));
    [borderLayer setBackgroundColor:[[UIColor whiteColor] CGColor]];
    [borderLayer setFrame:borderFrame];
    [borderLayer setCornerRadius:PROFILE_IMAGE_DIAMETER/2.0];
    [borderLayer setBorderWidth:PROFILE_IMAGE_BORDER_WIDTH+1.0];
    [borderLayer setBorderColor:[UIColor whiteColor].CGColor];

    [imageLayer addSublayer:borderLayer];
}

This method works fine as long as it's called after viewDidLoad, but will not add the border layer if called before viewDidLoad. I have confirmed that self.profileImageView has been allocated at the time of this method call, but I only get the circular image, no border.

Is there something that I am misunderstanding about CALayers? Should it matter when I add the layer as a sublayer?

The reason I am not using the border property directly on the image layer is that it leaves a tiny sliver of image around the outside that is displeasing.

4

2 に答える 2

1

私は答えを見つけました!問題は、profileImageViewフレームを使用してボーダーレイヤーのフレームを設定したいということでしたが、オートレイアウトを使用しているため、ビューが画面に表示されるまでプロパティが設定されません。

私はやった:

 /*! This function adds a border layer to the profile image view. */
- (void)addBorderLayerToProfileImageView {
    CALayer *borderLayer = [CALayer layer];
    CGRect borderFrame = CGRectMake(-1.0, -1.0, (PROFILE_IMAGE_DIAMETER+2.0), (PROFILE_IMAGE_DIAMETER+2.0));
    [borderLayer setBackgroundColor:[[UIColor clearColor] CGColor]];
    [borderLayer setFrame:borderFrame];
    [borderLayer setCornerRadius:PROFILE_IMAGE_DIAMETER/2.0];
    [borderLayer setBorderWidth:PROFILE_IMAGE_BORDER_WIDTH+1.0];
    [borderLayer setBorderColor:[UIColor whiteColor].CGColor];
    [self.profileImageView.layer addSublayer:borderLayer];
}

境界線レイヤーを追加した理由は、レイヤーの境界線が画像ビューの端と境界線の間に小さなアーティファクトを残すためです。

于 2013-08-20T23:13:48.203 に答える
1

私はあなたと同じ問題を抱えていました.サブレイヤーを呼び出さない限り、サブレイヤーが表示されませんviewDidAppear.

あなたの答えを見ましたが、うまくいきませんでした。私は AutoLayout を使用しているため、ビューの高さや幅がわからない動的なソリューションが必要でした。frame.sizeレイヤーを追加しようとしていた私のビューは、高さと幅の値が0になるまで(viewDidAppear意味があります)。

UIViewとのライフサイクルについてさらに学習した後、AutoLayout がその時点でビューを測定したため、カスタムUIViewControllerの関数を使用してサブビューを追加することで解決しました。layoutSubviews()UIView

AutoLayoutもこの時点で測定しUIViewControllerたため、関数のサブビューにレイヤーを追加することもできます。viewDidLayoutSubviews()

于 2019-01-28T16:08:35.600 に答える