UIView에서 선 그리기


86

UIView에 수평선을 그려야합니다. 가장 쉬운 방법은 무엇입니까? 예를 들어 y-coord = 200에 검은 색 수평선을 그리고 싶습니다.

Interface Builder를 사용하고 있지 않습니다.


1
다음은 모든 iOS에서 단일 픽셀 라인을 올바르게 사용하고 스토리 보드에서 쉽게 만드는 완벽하고 쉬운 솔루션입니다. stackoverflow.com/a/26525466/294884
Fattie

답변:


122

귀하의 경우 (수평선)에서 가장 쉬운 방법은 검정색 배경색과 프레임이있는 하위보기를 추가하는 것 [0, 200, 320, 1]입니다.

코드 샘플 (오류가 없기를 바랍니다-Xcode없이 작성했습니다) :

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 1)];
lineView.backgroundColor = [UIColor blackColor];
[self.view addSubview:lineView];
[lineView release];
// You might also keep a reference to this view 
// if you are about to change its coordinates.
// Just create a member and a property for this...

또 다른 방법은 drawRect 메서드에서 선을 그리는 클래스를 만드는 것입니다 ( 여기에 대한 코드 샘플을 볼 수 있습니다 ).


Storyboard에서 코드없이이 작업을 수행하십시오. 더 쉽고 좋습니다.
coolcool1994

3
@ coolcool1994, "인터페이스 빌더를 사용하고 있지 않습니다." 질문에 요구 사항?
마이클 케슬 러

312

조금 늦었을 수도 있지만 더 나은 방법이 있다고 덧붙이고 싶습니다. UIView 사용은 간단하지만 비교적 느립니다. 이 메서드는 뷰가 그리는 방식을 재정의하고 더 빠릅니다.

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);

    // Draw them with a 2.0 stroke width so they are a bit more visible.
    CGContextSetLineWidth(context, 2.0f);

    CGContextMoveToPoint(context, 0.0f, 0.0f); //start at this point

    CGContextAddLineToPoint(context, 20.0f, 20.0f); //draw to this point

    // and now draw the Path!
    CGContextStrokePath(context);
}

이 코드가 UIView에서 사용되는 경우이 샘플의 좌표는 뷰 또는 전체 화면의 경계에 상대적입니까?
ChrisP 2011 년

CGContextBeginPath(context);전에 전화 할 필요가 CGContextMoveToPoint(...);없습니까?
i_am_jorf 2011

37
보기를 사용하여 그렇게하는 것은 너무 끔찍하지 않습니다. 예를 들어 방향 변경 중에 암시 적 애니메이션을 수행 할 때 작업이 더 쉬워집니다. 하나만 있으면 다른 UIView가 그다지 비싸지 않고 코드가 훨씬 간단합니다.
i_am_jorf

또한 다음 코드를 사용하여 경계와 중간 점을 얻을 수 있습니다. CGPoint midPoint; midPoint.x = self.bounds.size.width / 2; midPoint.y = self.bounds.size.height / 2;
coolcool1994

1
맞다. "느리다"라는 말은 타당하지 않다. 화면에는 언제든지 수많은 간단한 UIView가 있습니다. 관련된 모든 처리와 함께 하나의 (!) 텍스트 문자를 그리면 채워진 UIView가 그려집니다.
Fattie 2014-10-23

30

Swift 3 및 Swift 4

이것은 뷰 끝에 회색 선을 그리는 방법입니다 (b123400의 답변과 동일한 아이디어)

class CustomView: UIView {

    override func draw(_ rect: CGRect) {
        super.draw(rect)
        
        if let context = UIGraphicsGetCurrentContext() {
            context.setStrokeColor(UIColor.gray.cgColor)
            context.setLineWidth(1)
            context.move(to: CGPoint(x: 0, y: bounds.height))
            context.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
            context.strokePath()
        }
    }
}

viewDidLayoutSubviews에서 호출하면 "if let 컨텍스트"가 실패합니다.
Oscar

14

텍스트없이 배경색으로 레이블을 추가하기 만하면됩니다. 원하는 좌표와 높이 및 너비를 설정하십시오. 수동으로 또는 Interface Builder를 사용하여 수행 할 수 있습니다.


11

이를 위해 UIBezierPath 클래스를 사용할 수 있습니다.

원하는만큼 선을 그릴 수 있습니다.

UIView 하위 클래스가 있습니다.

    @interface MyLineDrawingView()
    {
       NSMutableArray *pathArray;
       NSMutableDictionary *dict_path;
       CGPoint startPoint, endPoint;
    }

       @property (nonatomic,retain)   UIBezierPath *myPath;
    @end

그리고 선 그리기에 사용될 pathArray 및 dictPAth 객체를 초기화했습니다. 내 프로젝트에서 코드의 주요 부분을 작성하고 있습니다.

- (void)drawRect:(CGRect)rect
{

    for(NSDictionary *_pathDict in pathArray)
    {
        [((UIColor *)[_pathDict valueForKey:@"color"]) setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor)
        [[_pathDict valueForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
    }

    [[dict_path objectForKey:@"color"] setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor)
    [[dict_path objectForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];

}

touchesBegin 메서드 :

UITouch *touch = [touches anyObject];
startPoint = [touch locationInView:self];
myPath=[[UIBezierPath alloc]init];
myPath.lineWidth = currentSliderValue*2;
dict_path = [[NSMutableDictionary alloc] init];

touchesMoved 메서드 :

UITouch *touch = [touches anyObject];
endPoint = [touch locationInView:self];

 [myPath removeAllPoints];
        [dict_path removeAllObjects];// remove prev object in dict (this dict is used for current drawing, All past drawings are managed by pathArry)

    // actual drawing
    [myPath moveToPoint:startPoint];
    [myPath addLineToPoint:endPoint];

    [dict_path setValue:myPath forKey:@"path"];
    [dict_path setValue:strokeColor forKey:@"color"];

    //                NSDictionary *tempDict = [NSDictionary dictionaryWithDictionary:dict_path];
    //                [pathArray addObject:tempDict];
    //                [dict_path removeAllObjects];
    [self setNeedsDisplay];

touchesEnded 메서드 :

        NSDictionary *tempDict = [NSDictionary dictionaryWithDictionary:dict_path];
        [pathArray addObject:tempDict];
        [dict_path removeAllObjects];
        [self setNeedsDisplay];

11

다른 하나 (그리고 더 짧은) 가능성. drawRect 내부에 있다면 다음과 같습니다.

[[UIColor blackColor] setFill];
UIRectFill((CGRect){0,200,rect.size.width,1});

0

Guy Daher의 답변을 기반으로합니다.

나는 사용을 피하려고? GetCurrentContext ()가 nil을 반환하면 응용 프로그램 충돌이 발생할 수 있기 때문입니다.

나는 문을 확인하지 않을 것입니다.

class CustomView: UIView 
{    
    override func draw(_ rect: CGRect) 
    {
        super.draw(rect)
        if let context = UIGraphicsGetCurrentContext()
        {
            context.setStrokeColor(UIColor.gray.cgColor)
            context.setLineWidth(1)
            context.move(to: CGPoint(x: 0, y: bounds.height))
            context.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
            context.strokePath()
        }
    }
}

2
if절의 이유 가 옵션에서 상자를 풀기 위한 것이라면 guard대신 명령문 을 사용하는 것이 좋습니다.
Julio Flores

-1

텍스트없이 프레임 크기 (예 : 높이 = 1)에 해당하는 배경색으로 레이블을 추가합니다. 코드 또는 인터페이스 빌더를 통해 수행하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.