Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何以编程方式从视图控制器绘制线?_Ios_Objective C_Uiview_Uikit - Fatal编程技术网

Ios 如何以编程方式从视图控制器绘制线?

Ios 如何以编程方式从视图控制器绘制线?,ios,objective-c,uiview,uikit,Ios,Objective C,Uiview,Uikit,我有一个UIViewController。如何在其中一个以编程方式创建的视图中绘制线?创建UIView并将其添加为视图控制器视图的子视图。可以将此子视图的高度或宽度修改为非常小,使其看起来像一条线。如果需要绘制对角线,可以修改“子视图变换”特性 e、 画一条黑色的水平线。这是从视图控制器的实现中调用的 UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, 1)];

我有一个
UIViewController
。如何在其中一个以编程方式创建的视图中绘制线?

创建UIView并将其添加为视图控制器视图的子视图。可以将此子视图的高度或宽度修改为非常小,使其看起来像一条线。如果需要绘制对角线,可以修改“子视图变换”特性

e、 画一条黑色的水平线。这是从视图控制器的实现中调用的

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, 1)];
lineView.backgroundColor = [UIColor blackColor];
[self.view addSubview:lineView];

有两种常见的技术

  • 使用:

    • 创建一个
      UIBezierPath
      (用所需的坐标替换坐标):

    • 创建一个使用该
      UIBezierPath
      CAShapeLayer

      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中,您必须在.m文件中手动添加和导入
    头,但这不再是必需的(如果您启用了“启用模块”和“自动链接框架”构建设置)

  • 另一种方法是子类化
    UIView
    ,然后在方法中使用调用:

    • 创建一个
      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/情节提要或视图的基类,也可以让视图控制器以编程方式将其添加为子视图:

      PathView *pathView = [[PathView alloc] initWithFrame:self.view.bounds];
      pathView.backgroundColor = [UIColor clearColor];
      
      [self.view addSubview: pathView];
      

  • 上述两种方法的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


  • 您不应该这样做,但如果出于某种原因,您可以创建UIView的子类,例如名为
    DelegateDrawView
    ,它接受一个委托,该委托实现了如下方法

    - (void)delegateDrawView:(DelegateDrawView *)aDelegateDrawView drawRect:(NSRect)dirtyRect
    
    然后在方法-
    [DelegateDrawView drawRect:
    中,您应该调用您的委托方法

    但为什么要将视图代码放在控制器中呢


    您最好创建UIView的子类,在它的两个角之间画一条线,您可以使用一个属性来设置哪两个角,然后从视图控制器将视图定位到您想要的位置。

    以下是一个很酷的技巧,您可能会发现它很有用:

    在项目中包含本文的通用视图子类,然后可以将这类代码放入视图控制器中,以便动态创建绘制线条的视图:

    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在其上绘制线

    但是,它允许跳过子分类。由于我不太倾向于核心图形,所以我仍然可以使用它。您只需将其放入-
    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();
    
    除了Rob的回答之外,为了快速起见,第三种方法是使用
    UIImageView
    -掩盖它-xib视图。(这是在xcode 5中的xib上拖动时的默认UIImageView外观)


    干杯,还有+1

    深入你的观点非常简单,@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);
    }
    
    -(void)touchesbeated:(NSSet*)toucheevent:(UIEvent*)event
    {
    UITouch*touch=[[event AllTouchs]anyObject];
    起始点=[触摸位置视图:self.view];
    NSLog(@“触摸起点=x:%f触摸起点=y:%f”,触摸点.x,触摸点.y);
    }
    -(无效)触控取消:(NSSet*)触控事件:(UIEvent*)事件
    {
    }
    -(void)touchesend:(NSSet*)toucheevent:(UIEvent*)event
    {
    UITouch*touch=[[event AllTouchs]anyObject];
    touchPoint=[TouchLocationInView:self.view];
    NSLog(@“触摸端点=x:%f触摸端点=y:%f”,触摸点.x,触摸点.y);
    }
    -(无效)触摸移动:(NSSet*)触摸事件:(UIEvent*)事件
    {
    UITouch*touch=[[event AllTouchs]anyObject];
    touchPoint=[TouchLocationInView:self.view];
    UIBezierPath*路径=[UIBezierPath bezierPath];
    [路径移动点:CGPointMake(touchPoint.x,touchPoint.y)];
    [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
    起始点=接触点;
    CAShapeLayer*shapeLayer=[CAShapeLayer层];
    shapeLayer.path=[path CGPath];
    shapeLayer.strokeColor=[[UIColor blueColor]CGColor];
    shapeLayer.lineWidth=3.0;
    shapeLayer.fillColor=[[UIColor redColor]CGColor];
    [self.view.layer addSublayer:shapeLayer];
    NSLog(@“触摸移动点=x:%f触摸移动点=y:%f”,触摸点.x,触摸点.y);
    [self.view setNeedsDisplay];
    }
    -(void)tapGestureRecognizer:(UIGestureRecognizer*)识别器{
    CGPoint tappedPoint=[识别器位置视图:self.view];
    CGFloat xCoordinate=tappedPoint.x;
    CGFloat yCoordinate=tappedPoint.y;
    NSLog(@“使用UITapgestureRecognitor x:%f y:%f进行触摸”,x协调,y协调);
    }
    

    它将像一条线一样画出,手指移动到哪里去

    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)
    
    Swift 5.4 使用具有1或2点高度的UIView,并将其添加为视图控制器视图的子视图

    类分隔符:UIView{
    let line=UIView()
    重写初始化(帧:CGRect){
    super.init(frame:frame)
    配置()
    }
    必需初始化?(编码器:NSCoder){
    fatalError(“初始化(编码者:)尚未实现”)
    }
    私有函数配置(){
    背景颜色=.red
    添加子视图(行)
    line.translates自动调整大小gmaskintoConstraints=false
    line.backgroundColor=.secondaryLabelColor
    NSLayoutConstraint.activate([
    直线中心约束(等式:self.centerYAnchor),
    line.centerXAnchor.constraint(相等:sel
    
    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)