4

Anyone ever seen the problem of [UIColor initWithPatternImage] ignoring the alpha values of the PNG? If so, what's the best fix?

I am using a png as a background layer to my array of button objects and it contains several pre-set alpha values per pixel in the image that is to be used as a texture background. It loads fine as a pattern/texture-color, but it comes up with all key transparent area as opaque black.

It is important that I get the right alpha values so that the button images shows correctly. The button frames do not include the alpha shadows from the background as that is not the "clickable" portion of the button. Additionally, my button object's images and background images also makes use of transparency, so it really needs to have a clear background directly behind each button to let the proper true current color settings come through (lowest layer UIView will have its background color set to the current user's selected color). Setting just the single alpha value for the UIView layer containing this texture does not work for my needs either.

Any help would be appreciated. My current workaround would be to use fully-blown, repeatedly-programmed layout of several UIImageView using the png, instead of a single UIView with the pattern fill.

Here is a snippet of code, but it's pretty standard for turning a UIImage into a UIColor for use as a pattern/texture color:

    UIView *selectorView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,320)];
    UIColor *background  = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"SelectorViewBackground.png"]];

    selectorView.backgroundColor = background;

    [mainView addSubview:selectorView]; // pattern background layer. Add UIButtons on top of this selectorView layer
    [self addSubview:mainView]; // current user selected color set in mainView.
    [selectorView release];
    [background release];
Natchaphon S.
  • 41
  • 1
  • 2

4 Answers4

3

I had the same problem with setting a background on a UIView with some transparancy, this is how I solved it:

theView.backgroundColor = [UIColor clearColor];
theView.layer.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"the_image_with_transparancy.png"]].CGColor;
fredrik
  • 13,282
  • 4
  • 35
  • 52
  • That one worked for me most of the time, but the problem is that it may reverse the given image. A possible solution might be: http://stackoverflow.com/a/5917849/936957 – Yunus Nedim Mehel Mar 12 '13 at 12:49
1

This is probably related to:

Tiled Background Image: Can I do that easily with UIImageView?

Basically, try setting:

[view setOpaque:NO];
[[view layer] setOpaque:NO];
Community
  • 1
  • 1
Jai
  • 897
  • 9
  • 15
0

No I've never had an issue with this. I use code like the above all the time for apps (though often I use it in conjunction with a layer instead of a view but that shouldn't make a difference with transparency being recognized) and always have had transparency work fine.

I'd look into your PNG file. I've noticed iOS sometimes being finicky with certain PNG options/types (like an 8 bit PNG with 8 bit transparency). Make sure your PNG is saved as 24 bit with 8 bit transparency (32 bit total).

Also, stupid question, but have you verified there isn't anything black in the view/layer hierarchy behind your PNG? Sometimes it's the stupid things like that

Jay
  • 4,480
  • 3
  • 25
  • 22
  • Hi Jay, Thanks so much for your response. Yes, I triple checked the PNG, any views behind, and it is 32 bits total.As everything sits inside a scroll view so finally I opted to create multiple UIImageView stacked vertically based on number of rows of UIButtons and that did the trick, as it also easily scrolls with the array of UIButtons. The same PNG has the transparency working fine as a UIImageView. Some day if I have time I will check the difference when using layers. Cheers! :) – Natchaphon S. Feb 24 '11 at 04:13
0

For those who might need the work-around code where the background patterns can be laid out as rows in a UIScrollView, here it is (adjusted to remove confidentiality concerns, should work if variables properly set prior to call).

Note that there should be ways to reuse just the one allocated instance of UIImageView multiple times to either save memory or load times but time-to-market is my No. 1 driver right now. Enjoy the journey :)

    UIImageView *selectorView;
    for (int i = 0; i < numRows; ++i) {
        selectorView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SelectorViewBackground.png"]];
        selectorView.frame = CGRectMake(0, i * patternHeight, patternWidth, patternHeight);
        [mainView addSubview:selectorView];
        [selectorView release];         
    }
Natchaphon S.
  • 41
  • 1
  • 2
  • if you're reusing the exact same image why are you creating a new one for each loop? Store the UIImage outside of the loop and then assign your view to it in the loop. Save you a bunch of calls and takes less time to do than I spent typing this comment. – Jay Feb 24 '11 at 07:17
  • I know. I thought about it as I copied the code into the posting. Pulling my hair out first to get all the stuff in for the deadline... I will clean it up shortly. Thanks again Jay. – Natchaphon S. Feb 24 '11 at 14:47