new stretchableImage
In einem aktuellen Projekt benötige ich Buttons bzw. ImageView’s mit Grafiken, welche sowohl abgerundete Ecken als auch einen Verlauf haben.
Ein komplett skalierter Verlauf hat den Nachteil, dass die abgerundeten Ecken auch verzogen sind — ein stretchableImage bringt dann zwar gute Ecken, allerdings nicht mehr den Verlauf.
Mein Ansatz ist der, dass ich das Bild zerschneide, den oberen und unteren Rand horizontal stretche, und den inneren Teil skaliere.
/**
* creates an UIImage with a similar behavior like stretchableImage, but it stretches also the
* whole content area, which is suitable for all kinds of vertical gradients
*/
- (UIImage *)imageNamed:(NSString *)name WithLeftCapWidth:(CGFloat)leftCapWidth topCapHeight:(CGFloat)topCapHeight frameRect:(CGRect) aframe{
UIImage *basicImg = [UIImage imageNamed:name];
CGRect topRect = CGRectMake(0.0, 0.0, basicImg.size.width, topCapHeight);
CGRect cropRect = CGRectMake(0.0, topCapHeight, basicImg.size.width, basicImg.size.height - (topCapHeight * 2));
CGRect bottomRect = CGRectMake(0.0,basicImg.size.height - topCapHeight, basicImg.size.width, topCapHeight);
// main area
CGImageRef imageRef = CGImageCreateWithImageInRect([basicImg CGImage], cropRect);
UIImage *cropImage = [[UIImage imageWithCGImage:imageRef] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:0];
CGImageRelease(imageRef);
// top area
CGImageRef imageRef2 = CGImageCreateWithImageInRect([basicImg CGImage], topRect);
UIImage *topImage = [[UIImage imageWithCGImage:imageRef2] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:0];
CGImageRelease(imageRef2);
// bottom area
CGImageRef imageRef3 = CGImageCreateWithImageInRect([basicImg CGImage], bottomRect);
UIImage *bottomImage = [[UIImage imageWithCGImage:imageRef3] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:0];
CGImageRelease(imageRef3);
UIGraphicsBeginImageContext(aframe.size);
[topImage drawInRect:CGRectMake(0.0, 0.0, aframe.size.width, topCapHeight)];
[cropImage drawInRect:CGRectMake(0.0, topCapHeight, aframe.size.width, aframe.size.height - (topCapHeight*2))];
[bottomImage drawInRect:CGRectMake(0.0, aframe.size.height - topCapHeight, aframe.size.width, topCapHeight)];
basicImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return basicImg;
}
In meinem Beispiel sieht das dann so aus:
Ursprungsgrafik:

Screenshot mit Skalierung:
