2014-10-07 1 views
1

У меня есть круговой индикатор выполнения в моем приложении, в котором отображается процент от бюджета пользователей, который они потратили. Индикатор выполнения должен обновляться каждый раз, когда пользователь переключается на представление с круговой индикацией выполнения. Он также должен обновлять каждый раз, когда пользователь открывает приложение.Обновление UIView с setNeedsDisplay не работает

В настоящее время, по какой-то причине я не понимаю, он будет обновляться только после открытия приложения (от закрытия в многозадачном режиме) и никогда не будет обновляться, если пользователь переключится на это представление (что ему нужно). Я провел много исследований, но не смог найти решение.

Вот код, который создает круг:

var progress: CGFloat = 0 

class ProgressCircle: UIView { 

override func drawRect(rect: CGRect) { 
    var ctx = UIGraphicsGetCurrentContext() 

    var innerRadiusRatio: CGFloat = 0.6 

    var path: CGMutablePathRef = CGPathCreateMutable() 
    var startAngle: CGFloat = CGFloat(-M_PI_2) 
    var endAngle: CGFloat = CGFloat(-M_PI_2) + min(1.0, progress) * CGFloat(M_PI * 2) 
    var outerRadius: CGFloat = CGRectGetWidth(self.bounds) * 0.5 - 1.0 
    var innerRadius: CGFloat = outerRadius * innerRadiusRatio 
    var center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)) 

    //Code for background circle 

    var context: CGContextRef = UIGraphicsGetCurrentContext() 
    colourTheme = NSUserDefaults.standardUserDefaults().integerForKey("themeSettings") 
    if colourTheme == 1 { 
     CGContextSetFillColorWithColor(context, (UIColorFromRGB(0xEAEAEA)).CGColor) 
    } else { 
     CGContextSetFillColorWithColor(context, (UIColor.darkGrayColor()).CGColor) 
    } 

    var circleSize: CGFloat = 0 
    switch height { 
    case 480, 568: 
     circleSize = 171 
    default: 
     circleSize = 250 
    } 

    var rectangle: CGRect = CGRectMake(0, 0, circleSize, circleSize) 
    CGContextBeginPath(context) 
    CGContextAddEllipseInRect(context, rectangle) 
    CGContextDrawPath(context, kCGPathFill) 

    UIGraphicsEndImageContext() 

    if colourTheme == 1 { 
     CGContextSetFillColorWithColor(context, (UIColor.darkGrayColor()).CGColor) 
    } else { 
     CGContextSetFillColorWithColor(context, (UIColorFromRGB(0xEAEAEA)).CGColor) 
    } 

    var circleXY: CGFloat = 0 
    var circleWH: CGFloat = 0 
    switch height { 
    case 480, 568: 
     circleXY = 35.95 
     circleWH = 99.1 
    default: 
     circleXY = 52 
     circleWH = 146 
    } 
    var rectangleSmall: CGRect = CGRectMake(circleXY, circleXY, circleWH, circleWH) //102.6 
    CGContextBeginPath(context) 
    CGContextAddEllipseInRect(context, rectangleSmall) 
    CGContextDrawPath(context, kCGPathFill) 

    UIGraphicsEndImageContext() 

    //Code for progress radius 

    CGPathAddArc(path, nil, center.x, center.y, innerRadius, startAngle, endAngle, false) 
    CGPathAddArc(path, nil, center.x, center.y, outerRadius, endAngle, startAngle, true) 
    CGPathCloseSubpath(path) 
    CGContextAddPath(ctx, path) 

    CGContextSaveGState(ctx) 
    CGContextClip(ctx) 
    if percent > 100 { 
     CGContextDrawImage(ctx, self.bounds, UIImage(named: "RadialProgressFillOver").CGImage) 
    } else { 
     CGContextDrawImage(ctx, self.bounds, UIImage(named: "RadialProgressFill").CGImage) 
    } 
    CGContextRestoreGState(ctx) 
} 

А вот код, который я использую, чтобы (попытаться), чтобы обновить круг прогресса. Этот код находится в viewDidAppear():

override func viewDidAppear(animated: Bool) { 
    //Show set up screen if user hasn't used AffordIt before. 

    userReturned = NSUserDefaults.standardUserDefaults().boolForKey("userReturnedCheck") 
    if userReturned == false { 
     self.performSegueWithIdentifier("setupView", sender: self) 
    } 

    //Add circular progress bar to budget display view. 

    var circleSize: CGFloat = 0 
    var yCoord: CGFloat = 0 
    switch height { 
    case 480, 568: 
     circleSize = 171 
     yCoord = 249 
    case 667: 
     circleSize = 250 
     yCoord = 249 
    default: 
     circleSize = 250 
     yCoord = 279 
    } 

    progress = CGFloat(percent/100) 
    var circleFrame = CGRect(x: (budgetDisplayView.bounds.width/2)-(circleSize/2), y: yCoord, width: circleSize, height: circleSize) 
    var circle = ProgressCircle(frame: circleFrame) 
    self.budgetDisplayView.addSubview(circle) 
    self.budgetDisplayView.sendSubviewToBack(circle) 
    circle.setNeedsDisplay() 
    view.setNeedsDisplay() 

    circle.backgroundColor = UIColor.clearColor() 
} 

Я действительно надеюсь, что кто-то имеет решение, потому что я имел эту проблему в течение примерно недели. Благодарю.

ответ

3

Каждый раз, когда появляется ваш контроллер представления и viewDidAppear() называется, вы создаете бренд новыйProgressCircle вид и отправить его на спину. Если вы не делаете это в другом месте, это не похоже, что вы удаляете ProgressCircle с budgetDisplayView. Я прав?

Если я прав, когда приложение открыто от полного закрытия viewDidAppear() будут называться в первый раз на этой точку зрения контроллера и одного круга прогресса будет создан и показан как вы наблюдаете. В следующий раз, когда будет показан контроллер вида, и снова будет вызван viewDidAppear(), еще один промежуточный круг создан и добавлен за созданным в последний раз! То же самое происходит каждый последующий раз. Я считаю, что вы этого не видите. В качестве быстрого теста (но не долгосрочного решения) попробуйте комментировать строку: self.budgetDisplayView.sendSubviewToBack(circle). Надеюсь, это поможет.

+0

Ничего себе. Это действительно проблема! Я бы никогда не заметил, что так большое спасибо! – user3746428

 Смежные вопросы

  • Нет связанных вопросов^_^