おそらく4つの他のビューは必要ありません.8つが必要です。 9つのスライスのそれぞれは、水平方向および垂直方向のスケーリングの異なる組み合わせを必要とし得ること
+----+-----+---------+
| | | |
+----+-----+---------|
| |fixed| |
| | | |
+----+-----+---------+
| | | |
| | | |
| | | |
+----+-----+---------+
注意:インナー「固定」矩形は、9つのスライスに視野を分割します。それはこのように見える終わる:とにかく
、私はそれだけでdrawRect:
をオーバーライドするUIView
サブクラスを作成することにより、これを行うにはあまりにも難しいことではないだろうと思いました。
私は私のサブクラスOutstretchView
を命名し、それを3つのプロパティを与えた:
@interface OutstretchView : UIView
@property (nonatomic) UIImage *image;
@property (nonatomic) CGRect fixedRect; // in image coordinates
@property (nonatomic) CGPoint fixedCenter; // in view coordinates
@end
fixedRect
プロパティを伸ばしてはいけません、画像の一部を定義します。 fixedCenter
プロパティは、ビューのどこにイメージの一部を描画するかを定義します。
イメージの9スライスを実際に描画するには、イメージ座標でCGRect
、ビュー座標でCGRect
を使用し、ビューの指定された部分にイメージの指定された部分を描画するメソッドを定義すると便利です。私はクォーツ2Dのクリップを使用して、CTMは「重労働」を行うことを特徴:
- (void)drawRect:(CGRect)imageRect ofImage:(UIImage *)image inRect:(CGRect)viewRect {
CGContextRef gc = UIGraphicsGetCurrentContext();
CGContextSaveGState(gc); {
CGContextClipToRect(gc, viewRect);
CGContextTranslateCTM(gc, viewRect.origin.x, viewRect.origin.y);
CGContextScaleCTM(gc, viewRect.size.width/imageRect.size.width, viewRect.size.height/imageRect.size.height);
CGContextTranslateCTM(gc, -imageRect.origin.x, -imageRect.origin.y);
[image drawAtPoint:CGPointZero];
} CGContextRestoreGState(gc);
}
私はまた、2つのX座標の配列と2つのY座標の配列からCGRect
を作成する小さなヘルパーメソッドを使用します:
static CGRect rect(CGFloat *xs, CGFloat *ys) {
return CGRectMake(xs[0], ys[0], xs[1] - xs[0], ys[1] - ys[0]);
}
これらのヘルパーでは、drawRect:
を実装できます。
CGPoint imageFixedCenter = self.fixedCenter;
CGRect viewFixedRect = CGRectOffset(imageFixedRect, imageFixedCenter.x - imageFixedRect.size.width/2, imageFixedCenter.y - imageFixedRect.size.height/2);
を:私は、画像の固定部分が描画される場所ビューの矩形座標計算
- (void)drawRect:(CGRect)dirtyRect {
UIImage *image = self.image;
if (!image)
return;
CGRect imageBounds = (CGRect){ CGPointZero, image.size };
CGRect viewBounds = self.bounds;
CGRect imageFixedRect = self.fixedRect;
if (CGRectIsNull(imageFixedRect)) {
[image drawInRect:viewBounds];
return;
}
:最初私は描画する画像、または全く定義fixedRect
ないかが存在しない簡単なケースを扱います
次に、ビュー座標空間内のスライスの辺を定義する4つの(4つの)X座標の配列と、Y座標の同様の配列と、イメージ座標空間の座標の2つの配列:
CGFloat viewSlicesX[4] = { viewBounds.origin.x, viewFixedRect.origin.x, CGRectGetMaxX(viewFixedRect), CGRectGetMaxX(viewBounds) };
CGFloat viewSlicesY[4] = { viewBounds.origin.y, viewFixedRect.origin.y, CGRectGetMaxY(viewFixedRect), CGRectGetMaxY(viewBounds) };
CGFloat imageSlicesX[4] = { imageBounds.origin.x, imageFixedRect.origin.x, CGRectGetMaxX(imageFixedRect), CGRectGetMaxX(imageBounds) };
CGFloat imageSlicesY[4] = { imageBounds.origin.y, imageFixedRect.origin.y, CGRectGetMaxY(imageFixedRect), CGRectGetMaxY(imageBounds) };
そして最後に簡単な部分、描画スライス:
for (int y = 0; y < 3; ++y) {
for (int x = 0; x < 3; ++x) {
[self drawRect:rect(imageSlicesX + x, imageSlicesY + y) ofImage:image inRect:rect(viewSlicesX + x, viewSlicesY + y)];
}
}
}
それは私のiPad 2
私のテストプロジェクトのこのバージョンはon githubあるにはほとんどラグです。
うわー、優秀な質問...私の思考プロセスは、それを偽造することです。黒いオーバーレイを追加しますが、UIViewには、実際には黒いオーバーレイの下にあるimageViewの部分だけを投影しています。 – CodaFi
しかし、下の部分にどのように黒いオーバーレイが見えますか?コンテンツrectに透明なビットがあるとします。 –
拡大表示するコンテンツとしてUIViewを受け入れる虫眼鏡のビューへのリンクです。私は実装を研究していないので、具体的な記述はできませんが、約束どおりに動作します:https://github.com/acoomans/iOS-MagnifyingGlass – CodaFi