0

我想创建“圆形”“半透明”UIView(或任何类似的东西)我的代码在下面产生动画效果,逐渐改变透明密度。我想要的是避免这种影响并从一开始就直接绘制结果图像。

谁能知道该怎么做?谢谢你。

- (id)initWithFrame:(CGRect)frame 
{
    if (self = [super initWithFrame:frame]) 
    {
        // Initialization code
        super.opaque = NO;
        self.alpha = 1.0f;
        self.strokeColor = kDefaultStrokeColor;
        super.backgroundColor = [UIColor clearColor];
        self.rectColor = kDefaultRectColor;
        self.strokeWidth = kDefaultStrokeWidth;
        self.cornerRadius = kDefaultCornerRadius;
        self.contentMode = UIViewContentModeRedraw;
        self.clearsContextBeforeDrawing = NO;
    }
    return self;
}
- (void)setBackgroundColor:(UIColor *)newBGColor
{
    // Ignore attempt to set backgroundColor
}
- (void)setOpaque:(BOOL)newIsOpaque
{
    // Ignore attempt to set opaque to YES.
}
- (void)drawRect:(CGRect)rect {
    BOOL areEnabled = [UIView areAnimationsEnabled];

    // with or without setAnimationsEnabled:NO gives me the same result
    [UIView setAnimationsEnabled:NO];

        // with or without beginAnimations and commitAnimations gives me the same result
    [UIView beginAnimations:@"test" context:nil];

    [UIView setAnimationRepeatCount:1];
//  [UIView setAnimationBeginsFromCurrentState:YES];

    // With or without setAnimationDelay gives me the same result
    //[UIView setAnimationDelay:0.0f];
        // With or without setAnimationDuration gives me the same result
        // passing 0.0f the same
    //[UIView setAnimationDuration:0.1f];


    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextBeginPath(context);

    CGContextSetLineWidth(context, strokeWidth);
    CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
    CGContextSetFillColorWithColor(context, self.rectColor.CGColor);

    CGRect rrect = self.bounds;

    CGFloat radius = cornerRadius;
    CGFloat width = CGRectGetWidth(rrect);
    CGFloat height = CGRectGetHeight(rrect);

    // Make sure corner radius isn't larger than half the shorter side
    if (radius > width/2.0)
        radius = width/2.0;
    if (radius > height/2.0)
        radius = height/2.0;    

    CGFloat minx = CGRectGetMinX(rrect);
    CGFloat midx = CGRectGetMidX(rrect);
    CGFloat maxx = CGRectGetMaxX(rrect);
    CGFloat miny = CGRectGetMinY(rrect);
    CGFloat midy = CGRectGetMidY(rrect);
    CGFloat maxy = CGRectGetMaxY(rrect);
    CGContextMoveToPoint(context, minx, midy);
    CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathFillStroke);
    CGContextClip(context); 

   [UIView commitAnimations];

   [UIView setAnimationsEnabled:areEnabled];

   // I am stacked...   
}
4

3 回答 3

2

以下是我在我一直在开发的 Cocoa Touch 应用程序中的做法:

[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
// Change opacity (or whatever) here.
[CATransaction commit];

不确定这是否是最好的方法(或者它是否甚至可以在 iPhone 环境之外工作),因为我自己有点 Cocoa 新手。不过,可能值得一试。

于 2009-10-24T09:50:51.990 回答
1

在 drawRect 中使用 UIView 动画是没有意义的。此外,不可能通过覆盖 UIView 属性来禁用动画,因为 CoreAnimation 动画层而不是视图属性。如果在使用其中一个视图时 alpha 消失,则问题不在于您的类的实现,而在于调用它的位置。[UIView beginAnimations]在设置您的视图或超级视图的 alpha 之前,一些周围的代码已经完成。

禁用所有动画,您可以使用 David 提出的方法。

于 2009-10-24T09:51:39.947 回答
1

从 3.0 开始,您可以轻松查看任何圆角:

1) 设置clipsToBoundsYES

2)设置view.layer.cornerRadius为某个值(5.0 相当不错,但您可以使用值)。这也要求您#import <QuartzCore/QuartzCore.h>在设置此属性的文件中。

全部完成!

如果您使用 IB 定义视图,则可以在 IB 中设置子视图剪辑,但不能修改图层属性,因此您必须在 viewDidLoad 或类似的地方添加该部分。

于 2009-10-24T22:16:05.917 回答