2011-09-22 78 views

回答

7

我會做的兩次迭代。
首先獲取上下文並開始一個路徑。填充一個橢圓,然後用三條線包圍一個三角形的自定義路徑。我假設以下尺寸:70寬度,62高度。覆蓋的UIView的子類繪製矩形並實例化在一個子類的UIViewController:當對一個灰色背景加入

-(void)drawRect:(CGRect)rect { 
    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    CGContextSetRGBFillColor(ctx, 0.0, 0.0, 1.0, 1.0); 
    CGContextFillEllipseInRect(ctx, CGRectMake(0.0, 0.0, 70.0, 50.0)); //oval shape 
    CGContextBeginPath(ctx); 
    CGContextMoveToPoint(ctx, 8.0, 40.0); 
    CGContextAddLineToPoint(ctx, 6.0, 50.0); 
    CGContextAddLineToPoint(ctx, 18.0, 45.0); 
    CGContextClosePath(ctx); 
    CGContextFillPath(ctx); 
} 

生成此在iPhone模擬器:

enter image description here

這第二代碼例如將幾乎重複上面生成的內容。我實現了這個使用靈活的大小,可以提供給UIView框架,當你實例化它。基本上,講話泡泡的白色部分是用黑色的筆觸畫出來的。

-(void)drawRect:(CGRect)rect { 
    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    CGRect aRect = CGRectMake(2.0, 2.0, (self.bounds.size.width * 0.95f), (self.bounds.size.width * 0.60f)); // set the rect with inset. 
    CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0); //white fill 
    CGContextSetRGBStrokeColor(ctx, 0.0, 0.0, 0.0, 1.0); //black stroke 
    CGContextSetLineWidth(ctx, 2.0); 


    CGContextFillEllipseInRect(ctx, aRect); 
    CGContextStrokeEllipseInRect(ctx, aRect);  

    CGContextBeginPath(ctx); 
    CGContextMoveToPoint(ctx, (self.bounds.size.width * 0.10), (self.bounds.size.width * 0.48f)); 
    CGContextAddLineToPoint(ctx, 3.0, (self.bounds.size.height *0.80f)); 
    CGContextAddLineToPoint(ctx, 20.0, (self.bounds.size.height *0.70f)); 
    CGContextClosePath(ctx); 
    CGContextFillPath(ctx); 

    CGContextBeginPath(ctx); 
    CGContextMoveToPoint(ctx, (self.bounds.size.width * 0.10), (self.bounds.size.width * 0.48f)); 
    CGContextAddLineToPoint(ctx, 3.0, (self.bounds.size.height *0.80f)); 
    CGContextStrokePath(ctx); 

    CGContextBeginPath(ctx); 
    CGContextMoveToPoint(ctx, 3.0, (self.bounds.size.height *0.80f)); 
    CGContextAddLineToPoint(ctx, 20.0, (self.bounds.size.height *0.70f)); 
    CGContextStrokePath(ctx); 
} 

enter image description here

0

我有另一種方式 - 但我沒有任何時間來好好解釋一下吧。

但是,我的例子是用.NET編寫的,用於Windows應用程序。

我的版本將整個演講泡泡創建爲2D多邊形網格並且部分可自定義。這是一個單一的繪製路徑,而不是多個部分。

雖然我們的平臺不一樣 - 該技術使用常見的數學例程和程序循環。我相信這項技術可以轉化爲其他編程語言或平臺。

Private Sub Generate(ByVal Resolution As Integer, Optional ByVal SpeachPointerAngle As Integer = (45 * 3), Optional ByVal PointerBend As Decimal = 15) 

     'Generated the same way we create vector (wireframe) mesh for an Ellipse but... 
     '... at a predefined defined angle we create 

     'the size of the Pointer TIP/Corner portion of the speach bubble 
     'in relation to the EDGE of the ELLIPSE (average) 
     Dim SpeachPointerSize As Integer = 30 

     If PointerBend > 10 Then PointerBend = 10 
     If PointerBend < -10 Then PointerBend = -10 

     'as a variable offset that should be limited to max +/- -15 to 15 degrees relative to current angle as a safe range 
     '- were speach pointer angle determins which side the the pointer appears 
     Dim PointerOffsetValue As Decimal = PointerBend 
     Dim ActualPointerAngle As Decimal 

     'SpeachPointerAngle = 360 - SpeachPointerAngle ' adjust orientation so that 0 degrees is SOUTH 

     'Ellipse Size: 
     Dim Size_X As Decimal = 80 
     Dim Size_Y As Decimal = 50 

     If Resolution < 30 Then Resolution = 30 

     Dim Result As Vector2() 

     'size of each angle step based on resolution (number of vectors) - Mesh Quality in otherwords. 
     Dim _Step As Decimal = 360/Resolution 

     'Our current angle as we step through the loop 
     Dim _CurrentAngle As Decimal = 0 

     'rounded values 
     Dim _LastAngle As Decimal = 0 
     Dim _NextAngle As Decimal = _Step 

     Dim SpeachDrawn As Boolean = False ' prevent creating more than 1 point to be safe 

     Dim I2 As Integer = 0 'need a stepper because of skipped IDS 

     'build the ellipse mesh 
     For i = 0 To Resolution - 1 

      _LastAngle = _CurrentAngle - 15 
      _NextAngle = _CurrentAngle + 15 

      ActualPointerAngle = _CurrentAngle 'side 
      ActualPointerAngle += PointerOffsetValue ' acual angle of point 

      Dim EX As Decimal = System.Math.Cos(Math.Deg2Rad(_CurrentAngle)) * Size_X 
      Dim EY As Decimal = System.Math.Sin(Math.Deg2Rad(_CurrentAngle)) * Size_Y 

      'Point extrusion size (trying to be even size all around) 
      Dim ExtrudeX As Decimal = System.Math.Cos(Math.Deg2Rad(_CurrentAngle)) * (Size_X + SpeachPointerSize) 
      Dim ExtrudeY As Decimal = System.Math.Sin(Math.Deg2Rad(_CurrentAngle)) * (Size_Y + SpeachPointerSize) 

      'is Pointer angle between Last and Next? 
      If SpeachPointerAngle > _LastAngle And SpeachPointerAngle < _NextAngle Then 
       If (SpeachDrawn = False) Then 
        ' the point for the speachbubble tip 
        Array.Resize(Result, I2 + 1) 

        Result(I2) = New Vector2(ExtrudeX, ExtrudeY) 
        SpeachDrawn = True 
        I2 += 1 
       Else 
        'skip 
       End If 
      Else 
       'normal ellipse vector 
       Array.Resize(Result, I2 + 1) 
       Result(I2) = New Vector2(EX, EY) 
       I2 += 1 
      End If 

      _CurrentAngle += _Step 

     Next 

     _Vectors = Result 
    End Sub 

上面的代碼生成此 - 繪製使用GDI + [DrawPolygon/FillPolygon]的位圖: https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash4/380262_10151202393414692_590995900_n.jpg

(對不起 - 我不能在這裏直接發佈圖像作爲我從未張貼在這裏之前,我沒有信譽尚未)

這是一個圖形彙編我爲它使用我自己的Vector2 .NET開發原始。

此語音泡泡在繪製時支持透明度 - 因爲它是單個多邊形而不是多個形狀。

基本上我們以編程方式繪製一個橢圓,然後在橢圓的所需邊上擠出一個演講點。

可以使用類似的方法來改用PointF結構。

代碼中的所有形狀都是圍繞原點0,0生成的。

添加向量時,也會逐漸調整數組的大小,以防止數組中的間隙。

EG - 演講泡泡的中心是原點0.0。

我很抱歉沒有正確解釋我的代碼 - 我只是沒有時間。 但它可能不太難理解。