私は持っていUIViewController
ます。プログラムで作成されたビューの1つに線を引くにはどうすればよいですか?
私は持っていUIViewController
ます。プログラムで作成されたビューの1つに線を引くにはどうすればよいですか?
回答:
2つの一般的な手法があります。
使用CAShapeLayer
:
作成UIBezierPath
(座標を必要なものに置き換えます):
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10.0, 10.0)];
[path addLineToPoint:CGPointMake(100.0, 100.0)];
CAShapeLayer
それを使用するを作成しますUIBezierPath
:
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 3.0;
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
それCAShapeLayer
をビューのレイヤーに追加します。
[self.view.layer addSublayer:shapeLayer];
以前のバージョンのXcodeでは、QuartzCore.frameworkをプロジェクトの「LinkBinary with Libraries」に手動で追加し、<QuartzCore/QuartzCore.h>
ヘッダーを.mファイルにインポートする必要がありましたが、これはもう必要ありません(「EnableModules」と「Link」がある場合)フレームワークを自動的に」ビルド設定をオンにします)。
もう1つのアプローチは、サブクラスUIView
化してから、メソッドでCoreGraphics呼び出しを使用するdrawRect
ことです。
UIView
サブクラスを作成し、drawRect
線を引くを定義します。
これはコアグラフィックスで実行できます。
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [[UIColor blueColor] CGColor]);
CGContextSetLineWidth(context, 3.0);
CGContextMoveToPoint(context, 10.0, 10.0);
CGContextAddLineToPoint(context, 100.0, 100.0);
CGContextDrawPath(context, kCGPathStroke);
}
または使用UIKit
:
- (void)drawRect:(CGRect)rect {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10.0, 10.0)];
[path addLineToPoint:CGPointMake(100.0, 100.0)];
path.lineWidth = 3;
[[UIColor blueColor] setStroke];
[path stroke];
}
次に、このビュークラスをNIB /ストーリーボードまたはビューの基本クラスとして使用するか、ViewControllerにプログラムでサブビューとして追加させることができます。
PathView *pathView = [[PathView alloc] initWithFrame:self.view.bounds];
pathView.backgroundColor = [UIColor clearColor];
[self.view addSubview: pathView];
上記の2つのアプローチのSwiftレンディションは次のとおりです。
CAShapeLayer
:
// create path
let path = UIBezierPath()
path.move(to: CGPoint(x: 10, y: 10))
path.addLine(to: CGPoint(x: 100, y: 100))
// Create a `CAShapeLayer` that uses that `UIBezierPath`:
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = UIColor.blue.cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = 3
// Add that `CAShapeLayer` to your view's layer:
view.layer.addSublayer(shapeLayer)
UIView
サブクラス:
class PathView: UIView {
var path: UIBezierPath? { didSet { setNeedsDisplay() } }
var pathColor: UIColor = .blue { didSet { setNeedsDisplay() } }
override func draw(_ rect: CGRect) {
// stroke the path
pathColor.setStroke()
path?.stroke()
}
}
そして、それをビュー階層に追加します。
let pathView = PathView()
pathView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(pathView)
NSLayoutConstraint.activate([
pathView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
pathView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
pathView.topAnchor.constraint(equalTo: view.topAnchor),
pathView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
pathView.backgroundColor = .clear
let path = UIBezierPath()
path.move(to: CGPoint(x: 10, y: 10))
path.addLine(to: CGPoint(x: 100, y: 100))
path.lineWidth = 3
pathView.path = path
上記では、PathView
プログラムで追加していますが、IBを介して追加することもでき、path
プログラムで設定するだけです。
shapeLayer.lineCap = kCALineCapRound;
UIBezierPath
を繰り返した単一の回線を使用することもできます。そして、あなたが好むかどうかを選ぶことができる か、または。addLineToPoint
addLine(to:)
shapeLayer.lineJoin = kCALineJoinRound
kCALineJoinBevel
kCALineJoinMiter
UIViewを作成し、それをViewControllerのビューのサブビューとして追加します。このサブビューの高さまたは幅を非常に小さく変更して、線のように見せることができます。対角線を描画する必要がある場合は、サブビューの変換プロパティを変更できます。
たとえば、黒い水平線を描画します。これは、ViewControllerの実装内から呼び出されます
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, 1)];
lineView.backgroundColor = [UIColor blackColor];
[self.view addSubview:lineView];
スウィフト3:
let path = UIBezierPath()
path.move(to: CGPoint(x: 10, y: 10))
path.addLine(to: CGPoint(x: 100, y: 100))
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = UIColor.blue.cgColor
shapeLayer.lineWidth = 3.0
view.layer.addSublayer(shapeLayer)
これが役に立つかもしれないクールなテクニックです:Objective-Cでのサブクラス化を避けるために描画にブロックを使用する
記事の汎用ビューサブクラスをプロジェクトに含めます。これは、線を引くビューをその場で作成するためにビューコントローラーに配置できる種類のコードです。
DrawView* drawableView = [[[DrawView alloc] initWithFrame:CGRectMake(0,0,320,50)] autorelease];
drawableView.drawBlock = ^(UIView* v,CGContextRef context)
{
CGPoint startPoint = CGPointMake(0,v.bounds.size.height-1);
CGPoint endPoint = CGPointMake(v.bounds.size.width,v.bounds.size.height-1);
CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
CGContextSetLineWidth(context, 1);
CGContextMoveToPoint(context, startPoint.x + 0.5, startPoint.y + 0.5);
CGContextAddLineToPoint(context, endPoint.x + 0.5, endPoint.y + 0.5);
CGContextStrokePath(context);
};
[self.view addSubview:drawableView];
UIImageViewを使用して線を引くことができます。
ただし、サブクラス化をスキップできます。そして、私はCore Graphicsに少し傾いているので、まだそれを使用できます。あなたはそれを入れることができます-ViewDidLoad
UIGraphicsBeginImageContext(self.view.frame.size);
[self.myImageView.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), 50, 50);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), 200, 200);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
self.myImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
ロブの答えに加えて、簡単に言うと、3番目のアプローチはUIImageView
、xibのビューを使用することです。(これは、xcode 5でxibにドラッグしたときのデフォルトのUIImageViewの外観です)
乾杯と+1!
実際にはそうすべきではありませんが、何らかの理由でそれが理にかなっている場合は、UIViewのサブクラスを作成できます。DelegateDrawView
たとえば、次のようなメソッドを実装するデリゲートを取ります。
- (void)delegateDrawView:(DelegateDrawView *)aDelegateDrawView drawRect:(NSRect)dirtyRect
次に、メソッドで-[DelegateDrawView drawRect:]
デリゲートメソッドを呼び出す必要があります。
しかし、なぜコントローラーにビューコードを配置したいのでしょうか。
UIViewのサブクラスを作成して、その2つのコーナーの間に線を引くことをお勧めします。プロパティを使用して、どちらのコーナーを設定し、ビューコントローラーから目的の場所にビューを配置できます。
ビュー内に描画するのは非常に簡単です、@ Mr.ROBは私が最初の方法をとった2つの方法を言いました。
コードをコピーして、必要な場所に貼り付けるだけです。
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
startingPoint = [touch locationInView:self.view];
NSLog(@"Touch starting point = x : %f Touch Starting Point = y : %f", touchPoint.x, touchPoint.y);
}
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
touchPoint = [touch locationInView:self.view];
NSLog(@"Touch end point =x : %f Touch end point =y : %f", touchPoint.x, touchPoint.y);
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
touchPoint = [touch locationInView:self.view];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
[path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
startingPoint=touchPoint;
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = [path CGPath];
shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
shapeLayer.lineWidth = 3.0;
shapeLayer.fillColor = [[UIColor redColor] CGColor];
[self.view.layer addSublayer:shapeLayer];
NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);
[self.view setNeedsDisplay];
}
- (void)tapGestureRecognizer:(UIGestureRecognizer *)recognizer {
CGPoint tappedPoint = [recognizer locationInView:self.view];
CGFloat xCoordinate = tappedPoint.x;
CGFloat yCoordinate = tappedPoint.y;
NSLog(@"Touch Using UITapGestureRecognizer x : %f y : %f", xCoordinate, yCoordinate);
}
指が動く線のように描画されます