У мене є UIViewController
. Як провести лінію в одному із програмно створених подань?
У мене є UIViewController
. Як провести лінію в одному із програмно створених подань?
Відповіді:
Є дві загальноприйняті техніки.
Використання 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 до "Зв’язати двійковий<QuartzCore/QuartzCore.h>
файл з бібліотеками" вашого проекту та імпортувати заголовок у ваш .m-файл, але це вже не потрібно (якщо у вас є "Увімкнути модулі" та "Посилання Frameworks Automatically "налаштування побудови ввімкнено).
Іншим підходом є підклас, UIView
а потім використання викликів CoreGraphics у drawRect
методі:
Створіть UIView
підклас і визначте, drawRect
який малює вашу лінію.
Ви можете зробити це за допомогою Core Graphics:
- (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 / розкадровки або перегляду, або ви можете зробити так, щоб ваш контролер перегляду програмно додав його як підпрогляд:
PathView *pathView = [[PathView alloc] initWithFrame:self.view.bounds];
pathView.backgroundColor = [UIColor clearColor];
[self.view addSubview: pathView];
Швидкі передачі двох вищевказаних підходів є такими:
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 і додайте його як підпрогляд подання контролера перегляду. Ви можете змінити висоту або ширину цього підпрогляду, щоб вони були дуже малими, щоб вони мали вигляд лінії. Якщо вам потрібно намалювати діагональну лінію, ви можете змінити властивість перегляду підпоглядів.
наприклад, намалювати чорну горизонтальну лінію. Це викликається в рамках реалізації вашого контролера подання
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();
Додаток до відповіді Роба: Для UIImageView
швидкого вибору третім підходом є використання - прикриття нею - подання xib. (Це зовнішній вигляд UIImageView за замовчуванням при перетягуванні на xib у xcode 5)
Вітаємо та +1!
Насправді не слід, але якщо з якихось причин це для вас має сенс, ви можете створити підклас UIView, який називається, DelegateDrawView
наприклад, який приймає делегата, який реалізує такий метод, як
- (void)delegateDrawView:(DelegateDrawView *)aDelegateDrawView drawRect:(NSRect)dirtyRect
а потім у методах - [DelegateDrawView drawRect:]
вам слід викликати метод делегата.
Але чому ви хочете помістити код перегляду у свій контролер.
Вам краще створити підклас UIView, який проводить лінію між двома його кутами, у вас може бути властивість встановлювати, які два, а потім розташувати подання там, де ви хочете, від контролера перегляду.
Малювати всередині свого зору дуже просто, @ 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);
}
Він буде намальований як лінія, куди рухається палець