Tengo un UIViewController
. ¿Cómo trazo una línea en una de sus vistas creadas mediante programación?
ios
objective-c
uiview
uikit
mkc842
fuente
fuente
Respuestas:
Hay dos técnicas comunes.
Usando
CAShapeLayer
:Crea un
UIBezierPath
(reemplaza las coordenadas con lo que quieras):UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(10.0, 10.0)]; [path addLineToPoint:CGPointMake(100.0, 100.0)];
Crea un
CAShapeLayer
que use esoUIBezierPath
:CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = [path CGPath]; shapeLayer.strokeColor = [[UIColor blueColor] CGColor]; shapeLayer.lineWidth = 3.0; shapeLayer.fillColor = [[UIColor clearColor] CGColor];
Agregue eso
CAShapeLayer
a la capa de su vista:[self.view.layer addSublayer:shapeLayer];
En versiones anteriores de Xcode, tenía que agregar manualmente QuartzCore.framework al "Enlace binario con bibliotecas" de su proyecto e importar el
<QuartzCore/QuartzCore.h>
encabezado en su archivo .m, pero eso ya no es necesario (si tiene "Activar módulos" y "Enlace Frameworks Automáticamente "configuración de compilación activada).El otro enfoque es crear una subclase
UIView
y luego usar llamadas a CoreGraphics en eldrawRect
método:Cree una
UIView
subclase y defina unadrawRect
que dibuje su línea.Puede hacer esto con 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); }
O usando
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]; }
Luego, puede usar esta clase de vista como la clase base para su NIB / storyboard o vista, o puede hacer que su controlador de vista lo agregue programáticamente como una subvista:
PathView *pathView = [[PathView alloc] initWithFrame:self.view.bounds]; pathView.backgroundColor = [UIColor clearColor]; [self.view addSubview: pathView];
Las interpretaciones Swift de los dos enfoques anteriores son las siguientes:
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
subclase: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() } }
Y agréguelo a su jerarquía de vista:
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
Arriba, estoy agregando
PathView
programáticamente, pero también puede agregarlo a través de IB, y simplemente configurarlopath
programáticamente.fuente
shapeLayer.lineCap = kCALineCapRound;
UIBezierPath
, con llamadasaddLineToPoint
/ repetidasaddLine(to:)
. Entonces puede elegir si prefiereshapeLayer.lineJoin = kCALineJoinRound
okCALineJoinBevel
okCALineJoinMiter
.Cree una UIView y agréguela como una subvista de la vista de su controlador de vista. Puede modificar el alto o el ancho de esta subvista para que sea muy pequeño para que se vea como una línea. Si necesita dibujar una línea diagonal, puede modificar la propiedad de transformación de las subvistas.
por ejemplo, dibuje una línea horizontal negra. Esto se llama desde la implementación de su controlador de vista
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, 1)]; lineView.backgroundColor = [UIColor blackColor]; [self.view addSubview:lineView];
fuente
Swift 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)
fuente
Aquí hay una técnica interesante que puede resultarle útil: usar bloques para dibujar para evitar subclases en Objective-C
Incluya la subclase de vista de propósito general del artículo en su proyecto, entonces este es el tipo de código que puede poner en su controlador de vista para crear una vista sobre la marcha que dibuje una línea:
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];
fuente
Puede usar UIImageView para dibujar líneas.
Sin embargo, permite omitir la subclasificación. Y como estoy poco inclinado a Core Graphics, todavía puedo usarlo. Puedes ponerlo en ...
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();
Además de la respuesta de Rob, para una rápida, el tercer enfoque es usar un
UIImageView
- cubrir con él - la vista de xib. (Esa es la apariencia predeterminada de UIImageView cuando se arrastra en xib en xcode 5)Saludos y +1!
fuente
Realmente no debería, pero si por alguna razón tiene sentido para usted, podría crear una subclase de UIView, llamada
DelegateDrawView
por ejemplo, que toma un delegado que implementa un método como- (void)delegateDrawView:(DelegateDrawView *)aDelegateDrawView drawRect:(NSRect)dirtyRect
y luego en los métodos,
[DelegateDrawView drawRect:]
debe llamar a su método delegado.Pero, ¿por qué querrías poner el código de vista en tu controlador?
Es mejor crear una subclase de UIView, que dibuje una línea entre dos de sus esquinas, puede tener una propiedad para establecer cuáles dos y luego colocar la vista donde la desee desde su controlador de vista.
fuente
Dibujar dentro de su vista es muy simple, @ Mr.ROB dijo 2 método Tomé el primer método.
Simplemente copie y pegue el código donde lo desee.
-(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); }
Dibujará como una línea, donde el dedo se mueve yendo
fuente