代码之家  ›  专栏  ›  技术社区  ›  s4y

iPhone:绘制旋转文本?

  •  6
  • s4y  · 技术社区  · 16 年前

    我想在视图中画一些文字,旋转90°。我对iPhone的开发还很陌生,浏览网页可以发现许多不同的解决方案。我试过几次,结果常常是我的文字被删掉了。

    这是怎么回事?我 在相当小的空间(表视图单元格)中绘制,但必须有一种“正确”的方法才能正确完成此操作?


    这里有几个例子。我正在尝试显示文本“ 12345 “沿着左边的黑条。

    1. RJShearman on the Apple Discussions

      CGContextRef context = UIGraphicsGetCurrentContext();
      CGContextSelectFont (context, "Helvetica-Bold", 16.0, kCGEncodingMacRoman);
      CGContextSetTextDrawingMode (context, kCGTextFill);
      CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0);
      CGContextSetTextMatrix (context, CGAffineTransformRotate(CGAffineTransformScale(CGAffineTransformIdentity, 1.f, -1.f ), M_PI/2));
      CGContextShowTextAtPoint (context, 21.0, 55.0, [_cell.number cStringUsingEncoding:NSUTF8StringEncoding], [_cell.number length]);
      CGContextRestoreGState(context);
      

      Attempt one. The one and part of the two are clipped out.
      (来源: deeptechinc.com

    2. 第二次尝试,来自 zgombosi on iPhone Dev SDK . 相同的结果(这里的字体稍微小一点,所以剪辑更少)。

      CGContextRef context = UIGraphicsGetCurrentContext();
      CGPoint point = CGPointMake(6.0, 50.0);
      CGContextSaveGState(context);
      CGContextTranslateCTM(context, point.x, point.y);
      CGAffineTransform textTransform = CGAffineTransformMakeRotation(-1.57);
      CGContextConcatCTM(context, textTransform);
      CGContextTranslateCTM(context, -point.x, -point.y);
      [[UIColor redColor] set];
      [_cell.number drawAtPoint:point withFont:[UIFont fontWithName:@"Helvetica-Bold" size:14.0]];
      CGContextRestoreGState(context);
      

      Attempt two. There is almost identical clipping http://dev.deeptechinc.com/sidney/share/iphonerotation/attempt2.png

    6 回复  |  直到 7 年前
        1
  •  7
  •   s4y    16 年前

    原来我桌上的手机是 总是

    要绘制更大的单元格,必须设置内容视图的 autoresizingMask

    cellContentView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
    

    cellContentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    

    drawRect 使用正确的大小调用。在某种程度上,这是有道理的,因为 UITableViewCell initWithStyle:reuseIdentifier: 没有提到单元格的大小,实际上只有表视图知道每行的大小,这取决于它自己的大小和它的委托对单元格的响应 tableView:heightForRowAtIndexPath:

    我读了报纸 Quartz 2D Programming Guide 直到绘图模型和功能开始有意义,绘制旋转文本的代码变得简单明了:

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextRotateCTM(context, -(M_PI/2));
    [_cell.number drawAtPoint:CGPointMake(-57.0, 5.5) withFont:[UIFont fontWithName:@"Helvetica-Bold" size:16.0]];
    CGContextRestoreGState(context);
    

    谢谢你的提示,看来我已经准备好了。

        2
  •  3
  •   Sorted    14 年前

    label.transform = CGAffineTransformMakeRotation(- 90.0f * M_PI / 180.0f);
    

        3
  •  2
  •   mahboudz    16 年前

    给你个提示。我猜你是用drawRect画画的。为什么不在drawRect周围画一个框架,看看rect有多大,如果这就是为什么要剪切。

    另一种方法是将文本放在UILabel中,然后在cellForRowAtIndexPath中创建单元格时将其旋转90度。

        4
  •  1
  •   Epsilon Prime    16 年前

    您了解UITableViewDelegate方法 heightForRowAtIndexPath

    这里有一个 simple tutorial on various graphics level methods. 假设您知道文本有多大,您应该能够适当调整表视图行的大小。

    此外,我会检查以确保任何转换后的边界实际上满足您的期望(使用调试器或log语句来验证)。

        5
  •  1
  •   BananaAcid    10 年前

    ruler screenshot

    RulerView : UIView
    
    
      // simple testing for iPhones (check for device descriptions to get all iPhones + iPads)
      - (float)getPPI
      {
          switch ((int)[UIScreen mainScreen].bounds.size.height) {
              case 568: // iPhone 5*
              case 667: // iPhone 6
                  return 163.0;
                  break;
    
              case 736: // iPhone 6+
                  return 154.0;
                  break;
    
              default:
                  return -1.0;
                  break;
          }
      }
    
      - (void)drawRect:(CGRect)rect
      {
          [[UIColor blackColor] setFill];
    
    
          float ppi = [self getPPI];
    
          if (ppi == -1.0)  // unable to draw, maybe an ipad.
              return;
    
          float linesDist = ppi/25.4; // ppi/mm per inch (regular size iPad would be 132.0, iPhone6+ 154.0)
    
          float linesWidthShort = 15.0;
          float linesWidthMid = 20.0;
          float linesWidthLong = 25.0;
    
          for (float i = 0, c = 0; i <= self.bounds.size.height; i = i + linesDist, c = c +1.0)
          {
              bool isMid = (int)c % 5 == 0;
              bool isLong = (int)c % 10 == 0;
    
              float linesWidth = isLong ? linesWidthLong : isMid ? linesWidthMid : linesWidthShort;
              UIRectFillUsingBlendMode( (CGRect){0, i, linesWidth, .5} , kCGBlendModeNormal);
    
    
    
              /*  FONT: Numbers without rotation (yes, is short)
              if (isLong && i > 0 && (int)c % 10 == 0)
                  [[NSString stringWithFormat:@"%d", (int)(c/10)] drawAtPoint:(CGPoint){linesWidthLong +2, i -5} withAttributes:@{
                                                                                                                                  NSFontAttributeName: [UIFont systemFontOfSize:9],
                                                                                                                                  NSBaselineOffsetAttributeName: [NSNumber numberWithFloat:1.0]
                                                                                                                                  }];
              */
    
    
              // FONT: Numbers with rotation (yes, requires more effort)
              if (isLong && i > 0 && (int)c % 10 == 0)
              {
                  NSString *str = [NSString stringWithFormat:@"%d", (int)(c/10)];
                  NSDictionary *attrs = @{
                                          NSFontAttributeName: [UIFont systemFontOfSize:9],
                                          NSBaselineOffsetAttributeName: [NSNumber numberWithFloat:0.0]
                                          };
                  CGSize textSize = [str sizeWithAttributes:attrs];
    
    
                  CGContextRef context = UIGraphicsGetCurrentContext();
                  CGContextSaveGState(context);
    
                  CGContextRotateCTM(context, +(M_PI/2));
                  [str drawAtPoint:(CGPoint){i - (textSize.width/2), -(linesWidthLong + textSize.height +2)} withAttributes:attrs];
    
                  CGContextRestoreGState(context);
              }
    
          }
      }
    
        6
  •  0
  •   dny238    16 年前

    当我发现我需要在文件顶部添加以下内容时,我喜欢Matt的方法。很简单。

    #define degreesToRadian(x) (M_PI * (x) / 180.0)
    

    mahboudz的建议可能是你阻力最小的途径。可以使用以下命令将UILabel旋转90度:[label setTransform:CGAffineTransformMakeRotation(DegreesToRadians(-90.0f));您只需根据标签宽度计算单元格高度-马特·朗11月10日0:09