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
CAShapeLayerque 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
CAShapeLayera 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
UIViewy luego usar llamadas a CoreGraphics en eldrawRectmétodo:Cree una
UIViewsubclase y defina unadrawRectque 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)UIViewsubclase: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 = pathArriba, estoy agregando
PathViewprogramáticamente, pero también puede agregarlo a través de IB, y simplemente configurarlopathprogramáticamente.fuente
shapeLayer.lineCap = kCALineCapRound;UIBezierPath, con llamadasaddLineToPoint/ repetidasaddLine(to:). Entonces puede elegir si prefiereshapeLayer.lineJoin = kCALineJoinRoundokCALineJoinBevelokCALineJoinMiter.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 ...
ViewDidLoadUIGraphicsBeginImageContext(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
DelegateDrawViewpor ejemplo, que toma un delegado que implementa un método como- (void)delegateDrawView:(DelegateDrawView *)aDelegateDrawView drawRect:(NSRect)dirtyRecty 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