想要“避免” UIView子类的动画效果

发布于 2024-08-08 23:54:20 字数 2967 浏览 2 评论 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...   
}

I want to create "rounded" "semi-transparent" UIView (or anything does similar)
my code below results in animation effects, gradually change transparent density.
What I want is to avoid this effects and draw the resulting image straight from the beginning.

Can anyone know how to do?
Thank you.

- (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...   
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

执妄 2024-08-15 23:54:20

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

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

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

Here's how I've done it in a Cocoa Touch application that I've been working on:

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

Not sure if this is the best way to do it (or if it'll even work outside the iPhone environment), as I'm a bit of a Cocoa novice myself. Could be worth a try, though.

鸢与 2024-08-15 23:54:20

在drawRect 中使用UIView 动画是没有意义的。此外,无法通过覆盖 UIView 属性来禁用动画,因为 CoreAnimation 对图层(而不是视图)属性进行动画处理。如果在使用其中一个视图时 alpha 消失,问题不在于类的实现,而在于调用它的位置。在设置视图或超级视图的 alpha 之前,一些周围的代码执行了 [UIView beginAnimations]

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

Using UIView animations from within drawRect is pointless. Also, it's not possible to disable animations by overwriting UIView properties since CoreAnimation animates layer—not view—properties. If the alpha fades when using one of you views, the problem is not in your classe's implementation, but from where it is called. Some surrounding code did [UIView beginAnimations] before setting your view's or superview's alpha.

Do disable all animations, you can use the method proposed by David.

烏雲後面有陽光 2024-08-15 23:54:20

从 3.0 开始,您可以轻松地实现任何视图圆角:

1) 将 clipsToBounds 设置为 YES

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

全部完成!

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

As of 3.0, you can have any view round corners easily:

1) Set clipsToBounds to YES.

2) set view.layer.cornerRadius to some value (5.0 is pretty good, but you can play with values). This also requires you to #import <QuartzCore/QuartzCore.h> in the file where you are setting this property.

All done!

If you are using IB to define views, you can set the subview clipping in IB but you can't modify the layer properties, so you'll have to add that part in viewDidLoad or somewhere similar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文