Ios UINavigationBar中的奇数动画(带有自定义视图的uiBarButtonim)

Ios UINavigationBar中的奇数动画(带有自定义视图的uiBarButtonim),ios,objective-c,uiview,uibarbuttonitem,Ios,Objective C,Uiview,Uibarbuttonitem,我试图在UINavigationBar中放置一个基于饼图的倒计时视图 被巧妙地称为ProgressView的UIView子类在添加到标准UIView时工作良好 然而,当我尝试在UINavigationBar/UINavigationItem中使用它作为uibarbuttonite的自定义视图时,事情变得有点不稳定 原因是,当计时器完成倒计时时,视图会变成一个绿色圆圈,该圆圈会缩小为一个绿点,以便不那么显眼 我正在初始化自定义UIBarButtonItem,如下所示: self.progressV

我试图在UINavigationBar中放置一个基于饼图的倒计时视图

被巧妙地称为ProgressView的UIView子类在添加到标准UIView时工作良好

然而,当我尝试在UINavigationBar/UINavigationItem中使用它作为uibarbuttonite的自定义视图时,事情变得有点不稳定

原因是,当计时器完成倒计时时,视图会变成一个绿色圆圈,该圆圈会缩小为一个绿点,以便不那么显眼

我正在初始化自定义UIBarButtonItem,如下所示:

self.progressView                      = [[ProgressView alloc] initWithFrame:CGRectMake(0, 0, 36, 36)];     
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.progressView];
以下是在计时器结束时运行的代码:

[UIView animateWithDuration:1.0f
                      delay:1.0f
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                     self.transform = CGAffineTransformScale(self.transform, 0.25f, 0.25f);
                 }
                 completion:nil];
我是否使用这个似乎并不重要:

self.transform = CGAffineTransformScale(self.transform, 0.25f, 0.25f);
或者这个:

self.transform = CGAffineTransformMakeScale(0.25f, 0.25f);
当我通过重写-voidsetFrame:CGRectframe访问器来监视自定义视图的frame属性时,我在iPhone 6 Plus上得到了以下输出测试:

frame: {{0, 0}, {0, 0}}
frame: {{0, 0}, {36, 36}}
frame: {{358, 4}, {36, 36}} // <-- This displays 3 times for some reason
frame: {{385, 17}, {9, 9}}
现在,很明显,帧宽度减少了27个点,导致UINavigationBar/UINavigationItem将整个视图向右移动,以在屏幕的右边缘保留一些缓冲区。我的计算似乎表明它保持了20点的缓冲

如何在不改变帧的情况下设置UIView收缩的动画?这幅画是如此的基本,在这一点上,它只是一个绿点,如果有办法的话,它看起来会缩小


我很满意一些能做到这一点的绘图技巧,但似乎对变换设置动画将获得最佳外观。

使用UIBezierPath/addArcWithCenter,您可以绘制一个圆

可以按如下方式模拟动画: 使用UIView类接收圆的半径并绘制圆。我们叫她圈吧

具有启动所需动画的方法。 此方法启动计时器,删除子视图圆(如果存在) 重新分配圆类,传递新半径并将其添加为子视图

这与你的情况不完全一样,但我认为会有所帮助

在您的按钮中:

- (void)drawCircularProgressBarWithMinutesLeft:(NSInteger)minutes secondsLeft:(NSInteger)seconds
{
    // Removing unused view to prevent them from stacking up
    for (id subView in [self subviews]) {
        if ([subView isKindOfClass:[CircularProgressTimer class]]) {
            [subView removeFromSuperview];
        }
    }
   // Init our view and set current circular progress bar value
    CGRect progressBarFrame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
    self.progressTimerView = [[CircularProgressTimer alloc] initWithFrame:progressBarFrame ];
    [self.progressTimerView setCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2)];
    [self.progressTimerView setPercent:seconds];

    // Here, setting the minutes left before adding it to the parent view
    [self.progressTimerView setMinutesLeft:minutes];
    [self.progressTimerView setSecondsLeft:seconds];
    [self addSubview:self.progressTimerView];
    self.progressTimerView = nil;
    [self setNeedsDisplay];
}
在UIView循环压缩计时器中

- (void)drawRect:(CGRect)rect
{
    // Create our arc, with the correct angles
    // The initialAngleFactor is the extra angular distance the stroke will cover from
    // angle zero to the desired initial angle. For example, if you want it to start from
    // angle zero, the factor will be zero. In this case, we'll start from 12 o'clock,
    // which is angle 3M_PI/2 or 1.5M_PI
    float initialAngleFactor = 1.5 * M_PI;
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath addArcWithCenter:CGPointMake(rect.size.width / 2, rect.size.height / 2)
                          radius:rect.size.width / 2 - indiceGrossuraLinha
                      startAngle:0 + initialAngleFactor
                        endAngle:(_percent * M_PI) / 30.0 + initialAngleFactor
                       clockwise:YES];

    // Are you wondering where the previous formula comes from?
    // (_percent * M_PI) / 30.0 + initialAngleFactor
    // Well, M_PI covers just half of the circle, which can display as much as 30 seconds.
    // That's the number of pieces in which the half circle is divided: 30 on each piece.
    bezierPath.lineWidth = 5;
    [[UIColor colorWithRed:0.03f green:0.64f blue:0.90f alpha:1.00f] setStroke]; 
//    [[UIColor colorWithRed:0.64f green:0.81f blue:0.99f alpha:1.00f] setStroke];
    [bezierPath stroke];
}

我的UIViewcontroller中有一个计时器在剩余分钟内调用DrawCircularProgressBar

我不知道你的意思。你能添加一些代码来解释你的想法吗?