9部構成の画像をお探しだと思います。9つの部分の画像は、左側と右側のみが垂直方向に、上下のみが水平方向にサイズ変更され、中央は軸のサイズが個別に変更され、コーナーはサイズ変更されません。
_____________
|c | hor | c|
|__|______|__|
| | | |
|v | axes |v |
|e |indep.|e |
|r | |r |
|__|______|__|
|c | hor |c |
|__|______|__|
Appleには、そのような画像を描くのに役立つ方法があります。NSDrawNinePartImage
ここ
では、画像を準備する必要があります。
初期化コードは次のようになります。
static NSImage *baseImage = NULL;
static NSImage *topLeftCornerImage;
static NSImage *topEdgeImage;
static NSImage *topRightCornerImage;
static NSImage *leftEdgeImage;
static NSImage *centerImage;
static NSImage *rightEdgeImage;
static NSImage *bottomLeftCornerImage;
static NSImage *bottomEdgeImage;
static NSImage *bottomRightCornerImage;
+ (void)initialize;
{
if (baseImage) return;
//46x46
baseImage = [NSImage imageNamed:@"badge.png"];
topLeftCornerImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 22)];
[topLeftCornerImage lockFocus];
[baseImage drawInRect:NSMakeRect(0,0,22,22)
fromRect:NSMakeRect(0.0,24,22,22)
operation:NSCompositeCopy fraction:1.0];
[topLeftCornerImage unlockFocus];
topEdgeImage = [[NSImage alloc] initWithSize:NSMakeSize(2, 22)];
[topEdgeImage lockFocus];
[baseImage drawInRect:NSMakeRect(0,0,2,22)
fromRect:NSMakeRect(22,24,2,22)
operation:NSCompositeCopy fraction:1.0];
[topEdgeImage unlockFocus];
topRightCornerImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 22)];
[topRightCornerImage lockFocus];
[baseImage drawInRect:NSMakeRect(0,0,22,22)
fromRect:NSMakeRect(24,24,22,22)
operation:NSCompositeCopy fraction:1.0];
[topRightCornerImage unlockFocus];
leftEdgeImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 2)];
[leftEdgeImage lockFocus];
[baseImage drawInRect:NSMakeRect(0,0,22,2)
fromRect:NSMakeRect(0,22,22,2)
operation:NSCompositeCopy fraction:1.0];
[leftEdgeImage unlockFocus];
centerImage = [[NSImage alloc] initWithSize:NSMakeSize(2, 2)];
[centerImage lockFocus];
[baseImage drawInRect:NSMakeRect(0,0,2,2)
fromRect:NSMakeRect(22,22,2,2)
operation:NSCompositeCopy fraction:1.0];
[centerImage unlockFocus];
rightEdgeImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 2)];
[rightEdgeImage lockFocus];
[baseImage drawInRect:NSMakeRect(0,0,22,2)
fromRect:NSMakeRect(24,24,22,2)
operation:NSCompositeCopy fraction:1.0];
[rightEdgeImage unlockFocus];
bottomLeftCornerImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 22)];
[bottomLeftCornerImage lockFocus];
[baseImage drawInRect:NSMakeRect(0,0,22,22)
fromRect:NSMakeRect(0,0,22,22)
operation:NSCompositeCopy fraction:1.0];
[bottomLeftCornerImage unlockFocus];
bottomEdgeImage = [[NSImage alloc] initWithSize:NSMakeSize(2, 22)];
[bottomEdgeImage lockFocus];
[baseImage drawInRect:NSMakeRect(0, 0, 2, 22)
fromRect:NSMakeRect(22, 0, 2, 22)
operation:NSCompositeCopy fraction:1.0];
[bottomEdgeImage unlockFocus];
bottomRightCornerImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 22)];
[bottomRightCornerImage lockFocus];
[baseImage drawInRect:NSMakeRect(0,0,22,22)
fromRect:NSMakeRect(24,0,22,22)
operation:NSCompositeCopy fraction:1.0];
[bottomRightCornerImage unlockFocus];
}
drawingCode:
NSDrawNinePartImage([self bounds],
topLeftCornerImage, topEdgeImage, topRightCornerImage,
leftEdgeImage, centerImage, rightEdgeImage,
bottomLeftCornerImage, bottomEdgeImage, bottomRightCornerImage,
NSCompositeSourceOver, 1.0, NO);
これは、CALayerベースの9つの部分からなる画像(NinePartLayer)の私の実現の別の例です。
NinePartLayer.h
#import <Foundation/Foundation.h>
@interface NinePartLayer : CALayer {
@private
NSSize _blockSize;
NSMutableArray* layers;
NSMutableArray* _images;
}
+ (NinePartLayer*) layerWithImage:(NSImage*)aImage;
@property (assign)NSSize blockSize;
- (void) setImage:(NSImage*)aImage;
@end
NinePartLayer.m
#import "NinePartLayer.h"
@interface NinePartLayer()
@property (retain)NSMutableArray* layers;
@property (retain)NSMutableArray* images;
@end
@implementation NinePartLayer
@synthesize images = _images;
@synthesize blockSize = _blockSize;
@synthesize layers;
+(NSImage*) imageFromImage:(NSImage *)anImage rect:(NSRect)aRect
{
@try {
NSPoint point = { -aRect.origin.x, -aRect.origin.y };
NSImage *theImage = [[self alloc] initWithSize:aRect.size];
[theImage lockFocus];
[anImage compositeToPoint:point operation:NSCompositeCopy];
[theImage unlockFocus];
[theImage autorelease];
return theImage;
}
@catch (NSException *exception) {
NSLog(@"%@",[exception description]);
return nil;
}
}
+ (NinePartLayer*) layerWithImage:(NSImage*)aImage
{
NinePartLayer* newLayer = [NinePartLayer layer];
[newLayer setImage:aImage];
return newLayer;
}
- (id)init {
self = [super init];
if (self) {
self.layers = [NSMutableArray array];
self.images = [NSMutableArray array];
}
return self;
}
- (void) updateLayers
{
for (int i = 0; i < 3 && i < [self.images count]; ++i) {
NSMutableArray* row = [self.images objectAtIndex:i];
for (int j = 0; j < 3 && j < [row count]; ++j) {
CALayer* item = [row objectAtIndex:j];
float x,y,width,height;
if(i == 0){
y = 0;
height = floorf(self.blockSize.height);
} else if(i == 1){
y = ceilf(self.blockSize.height);
height = self.frame.size.height - 2*self.blockSize.height;
} else if(i == 2){
y = self.frame.size.height - self.blockSize.height;
height = self.blockSize.height;
};
if(j == 0){
x = 0;
width = self.blockSize.width;
} else if(j == 1){
x = self.blockSize.width;
width = self.frame.size.width - 2*self.blockSize.width;
} else if(j == 2){
x = self.frame.size.width - self.blockSize.width;
width = self.blockSize.width;
};
item.frame = CGRectMake(x, y, width, height);
float delta=0;
if((i==1)&&(j==0))
{
item.frame = CGRectMake(x, y-delta, width+delta, height+2*delta);
}
if((i==2)&&(j==1))
{
item.frame = CGRectMake(x-delta, y-delta, width+2*delta, height+delta);
}
if((i==1)&&(j==2))
{
item.frame = CGRectMake(x-delta, y-delta, width+delta, height+2*delta);
}
if((i==0)&&(j==1))
{
item.frame = CGRectMake(x-delta, y, width+2*delta, height+delta);
}
}
}
}
- (void) setImage:(NSImage*)aImage
{
for(int i = 0; i < [self.layers count]; ++i)
[[self.layers objectAtIndex:i] removeFromSuperlayer];
[self.layers removeAllObjects];
self.images = [NSMutableArray array];
self.layers = [NSMutableArray array];
if(!aImage)
return;
for (int i = 0; i < 3; ++i) {
NSMutableArray* row = [NSMutableArray array];
for (int j = 0; j < 3; ++j) {
NSImage* img = [NSImage imageFromImage:aImage
rect:NSMakeRect((float)j/3.0*[aImage size].width,
(float)i/3.0*[aImage size].height,
1.0/3.0*[aImage size].width,
1.0/3.0*[aImage size].height)];
self.blockSize = NSMakeSize(1.0/3.0*[aImage size].width, 1.0/3.0*[aImage size].height);
CALayer* item = [CALayer layer];
[item performSelectorOnMainThread:@selector(setContents:) withObject:img waitUntilDone:NO];
[item performSelectorOnMainThread:@selector(setContentsGravity:) withObject:kCAGravityResize waitUntilDone:NO];
[self performSelectorOnMainThread:@selector(addSublayer:) withObject:item waitUntilDone:NO];
[row addObject:item];
[self.layers addObject:item];
}
[self.images addObject:row];
}
[self performSelectorOnMainThread:@selector(updateLayers) withObject:nil waitUntilDone:NO];
}
- (void) setFrame:(CGRect)frame
{
[super setFrame:frame];
[self updateLayers];
}
- (void) setBounds:(CGRect)bounds
{
[super setBounds:bounds];
[self updateLayers];
}
- (void) setPosition:(CGPoint)position
{
[super setPosition:position];
[self updateLayers];
}
- (void)dealloc {
self.layers = nil;
self.images = nil;
[super dealloc];
}
@end
利用方法:
NinePartLayer * pageContainerShadowlayer=[NinePartLayer layerWithImage:[NSImage imageNamed:@"drop_shadow.png"]];
pageContainerShadowlayer.frame=[mainView layer].bounds;
pageContainerShadowlayer.autoresizingMask=kCALayerWidthSizable | kCALayerHeightSizable;
[[rootView layer] insertSublayer:pageContainerShadowlayer atIndex:3];