自定义iOS按钮类不会在运行时显示

时间:2013-05-26 17:02:26

标签: iphone ios cgrect

我有一个使用Paintcode生成的自定义按钮类。它看起来像这样:

//
//  TGCustomConfirmButton.m
//  Indego
//
//  Created by 
//  Copyright
//

#import "TGCustomConfirmButton.h"

@implementation TGCustomConfirmButton

+ (TGCustomConfirmButton *)buttonWithType:(UIButtonType)type
{
  return [super buttonWithType:UIButtonTypeCustom];
}

- (void)drawRect:(CGRect)rect
{
  NSLog(@"drawRect enter");

  //// General Declarations
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = UIGraphicsGetCurrentContext();

  //// Color Declarations
  UIColor* strokeColor =    [UIColor colorWithRed: 0.143 green: 0.429 blue: 0 
                                            alpha: 1];
  UIColor* shadowColor2 =   [UIColor colorWithRed: 0.712 green: 0.972 blue: 0.489 
                                            alpha: 1];
  UIColor* gradientColor =  [UIColor colorWithRed: 0.391 green: 0.925 blue: 0.262 
                                            alpha: 1];
  UIColor* gradientColor2 = [UIColor colorWithRed: 0.052 green: 0.454 blue: 0.044 
                                            alpha: 1];
  UIColor* fillColor2 =     [UIColor colorWithRed: 0.833 green: 0.833 blue: 0.833 
                                            alpha: 1];
  UIColor* gradientColor3 = [UIColor colorWithRed: 1 green: 1 blue: 1 
                                            alpha: 1];

  //// Gradient Declarations
  NSArray* greenHighlightColors = [NSArray arrayWithObjects:
                                   (id)gradientColor.CGColor,
                                   (id)[UIColor colorWithRed: 0.221 green: 0.69 
                                            blue: 0.153 alpha: 1].CGColor,
                                   (id)gradientColor2.CGColor, nil];
  CGFloat greenHighlightLocations[] = {0, 0.23, 0.58};
  CGGradientRef greenHighlight = CGGradientCreateWithColors(colorSpace, 
                                            (__bridge CFArrayRef)greenHighlightColors,
                                              greenHighlightLocations);
  NSArray* innerShadow002Colors = [NSArray arrayWithObjects:
                                   (id)fillColor2.CGColor,
                                   (id)[UIColor colorWithRed: 0.917 green: 0.917 
                                            blue: 0.917 alpha: 1].CGColor,
                                   (id)gradientColor3.CGColor, nil];
  CGFloat innerShadow002Locations[] = {0, 0, 0.66};
  CGGradientRef innerShadow002 = CGGradientCreateWithColors(colorSpace, 
                                            (__bridge CFArrayRef)innerShadow002Colors,
                                             innerShadow002Locations);

  //// Shadow Declarations
  UIColor* shadow3 = shadowColor2;
  CGSize shadow3Offset = CGSizeMake(0.1, 3.1);
  CGFloat shadow3BlurRadius = 0;

  //// Rounded Rectangle 2 Drawing
  UIBezierPath* roundedRectangle2Path = [UIBezierPath bezierPathWithRoundedRect: 
                                        CGRectMake(36, 913, 577, 126) cornerRadius: 11];
  CGContextSaveGState(context);
  [roundedRectangle2Path addClip];
  CGContextDrawLinearGradient(context, innerShadow002, CGPointMake(324.5, 913),
                                             CGPointMake(324.5, 1039), 0);
  CGContextRestoreGState(context);


  //// Rounded Rectangle Drawing
  UIBezierPath* roundedRectanglePath=[UIBezierPath bezierPathWithRoundedRect: 
                                     CGRectMake(48.5, 926, 550, 86.5) cornerRadius: 6];
  CGContextSaveGState(context);
  [roundedRectanglePath addClip];
  CGContextDrawLinearGradient(context, greenHighlight, CGPointMake(323.5, 926),
                                    CGPointMake(323.5, 1012.5), 0);
  CGContextRestoreGState(context);

  ////// Rounded Rectangle Inner Shadow
  CGRect roundedRectangleBorderRect = CGRectInset([roundedRectanglePath bounds], 
                                            -shadow3BlurRadius, -shadow3BlurRadius);
  roundedRectangleBorderRect = CGRectOffset(roundedRectangleBorderRect, 
                                        -shadow3Offset.width, -shadow3Offset.height);
  roundedRectangleBorderRect = CGRectInset(CGRectUnion(roundedRectangleBorderRect,
                                             [roundedRectanglePath bounds]), -1, -1);

  UIBezierPath* roundedRectangleNegativePath = [UIBezierPath bezierPathWithRect:
                                             roundedRectangleBorderRect];
  [roundedRectangleNegativePath appendPath: roundedRectanglePath];
  roundedRectangleNegativePath.usesEvenOddFillRule = YES;

  CGContextSaveGState(context);
  {
    CGFloat xOffset = shadow3Offset.width 
                      + round(roundedRectangleBorderRect.size.width);
    CGFloat yOffset = shadow3Offset.height;
    CGContextSetShadowWithColor(context,
                                CGSizeMake(xOffset + copysign(0.1, xOffset),
                                             yOffset + copysign(0.1, yOffset)),
                                shadow3BlurRadius,
                                shadow3.CGColor);

    [roundedRectanglePath addClip];
    CGAffineTransform transform = 
                    CGAffineTransformMakeTranslation
                          (-round(roundedRectangleBorderRect.size.width), 0);
    [roundedRectangleNegativePath applyTransform: transform];
    [[UIColor grayColor] setFill];
    [roundedRectangleNegativePath fill];
  }
  CGContextRestoreGState(context);

  [strokeColor setStroke];
  roundedRectanglePath.lineWidth = 1.5;
  [roundedRectanglePath stroke];


  //// Cleanup
  CGGradientRelease(greenHighlight);
  CGGradientRelease(innerShadow002);
  CGColorSpaceRelease(colorSpace);

  NSLog(@"drawRect exit");

}

@end

此代码正在应用于UIButton,其类型已设置为custom。按钮位于应用程序的两个位置(还有更多的开发时间),一次位于UITableView下方的视图内,一次位于普通平面Jane UIViewController内。在这两种情况下,按钮的标签文本在运行时呈现,但按钮本身的设计无处可见。

有许多教程可以使用PaintCode绘制内容(我不需要帮助),但是如果在创建自定义按钮类后如何实现自定义按钮类则为零。我在使用非PaintCode创建的类之前已经完成了这个,而且非常确定我说得对。知道我哪里错了吗?

4 个答案:

答案 0 :(得分:2)

请参阅我的评论,同样来自Apple Docs:

+ (id)buttonWithType:(UIButtonType)buttonType
  

此方法是一种便捷构造函数,用于创建具有特定配置的按钮对象。它是UIButton的子类,此方法不返回子类的实例。如果要创建特定子类的实例,则必须直接分配/初始化该按钮。

答案 1 :(得分:1)

您没有看到背景颜色/渐变的原因是因为drawRect代码上的CGPoints是硬编码的。所以笔画和填充可能不会在按钮rect中发生。

我换了:

CGRectMake(36,913,577,126),带有rect,

CGPointMake(324.5,913)with rect.origin,

带有CGPointMake的CGPointMake(323.5,1012.5)(rect.origin.x + rect.size.width,rect.origin.y + rect.size.height)

我几乎能够获得背景填充和渐变。您可能需要根据您的要求进行一些调整。

我使用了按钮,通过向xib添加一个按钮并将其类更改为TGCustomConfirmButton

答案 2 :(得分:0)

避免使用buttonWithType

TGCustomConfirmButton *button = [[TGCustomConfirmButton alloc] initWithFrame:CGRectZero];

或者像这样做

+ (TGCustomConfirmButton *)buttonWithType:(UIButtonType)type {
  return type==UIButtonTypeCustom ? [[self alloc] init] : [super buttonType:type];
}

用法:

TGCustomConfirmButton *button = [TGCustomConfirmButton buttonWithType:UIButtonTypeCustom];

答案 3 :(得分:0)

对于后代和其他寻求PaintCode帮助的人来说,这是我们的解决方案。

在PaintCode中,您可以创建任何您喜欢的画布大小。我的印象是,与Illustrator一样,PaintCode只会渲染艺术,而实际上是艺术。相反,它会尝试在提供的空间中渲染画布中的所有内容。所以,就我而言,它试图将640x1136画布渲染成300x44按钮。从某种意义上说,它正在发挥作用;我画布顶部的白色渲染到按钮的画布上。

简而言之,在PaintCode中创建按钮和其他控件时,您需要注意您正在设计的元素的大小。即便如此,300x44 PaintCode设计也无法完美呈现在那个尺寸的按钮上。我发现我需要在我正在调用自定义类的元素的右侧和底部计划一些丢失的像素。我会更多地使用它,也可能解决这个问题。

无论如何,感谢所有答案。正如我所说,我希望这有助于某人。