Пользовательский UIProgressView в iOS7 невозможен?

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

Моя проблема - это высота моего UIProgressView. Хотя в iOS6 все работало, как ожидалось, теперь в iOS7 все идет не так.

Я попробовал следующее:

  • 1.Настройка пользовательского макета в методе drawRect:

Работает как шарм в iOS6, но в iOS7 прогресс устанавливается на 100% с самого начала, или панель очень тонкая.

  • 2.Настройка макета с помощью свойства progressImage и trackImage внешнего вида UIProgressView

Также не работает под iOS7. Здесь прогресс бара также устанавливается на 100% с самого начала. Некоторые люди пишут, что это должно быть возможно таким образом, но я не могу подтвердить это для iOS7.

  • 3.Использование initWithProgressStyle для инициализации, а затем установка кадра представления прогресса

Не работает для меня под iOS6 и iOS7. В iOS7 полосы просто очень тонкие.

Для меня сейчас это довольно неприятно, потому что бары либо на 100%, либо мега-тонкие. Может ли кто-нибудь дать мне предложение достичь старого макета моих взглядов на прогресс. Я думаю, что это должно быть возможно, потому что, если я посмотрю на свое приложение Spotify на iPhone (iOS7 установлен), представление прогресса выглядит как раньше.

enter image description here

Большое спасибо!

Ответ 1

Хорошо, проблема заключается в том, что iOS6 UIProgressView и iOS7 UIProgressView имеют разные внутренние структуры subviews. Представление прогресса iOS6 представляет собой единое представление без дочернего представления (или небольшое представление), в представлении прогресса iOS7 есть несколько дополнительных подпрограмм для рисования индикатора выполнения и фона.

Если вы удалите все subview UIProgressView на iOS7, чем drawRect: метод будет работать так же, как и раньше, на iOS6, но вы несете полную ответственность за то, что вы рисуете контент прогресса, включая индикатор выполнения и фон.

- (id) initWithCoder: (NSCoder*)aDecoder
{
    if(self=[super initWithCoder: aDecoder])
    {
            // Also you can setup height of your progress here
            // self.frame = CGRectMake(0,0,100,yourHeight);

        NSArray *subViews = self.subviews;
        for(UIView *view in subViews)
        {
            [view removeFromSuperview];
        }
    }
    return self;
}

Ответ 2

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

Я написал подкласс UIView с круглыми углами и вид внутри, который меняет свой размер в зависимости от данного прогресса. Я использую только цвета для фона, но изображения также возможны. Вот код:

#import "CustomProgressView.h"
#import <QuartzCore/QuartzCore.h>

@interface CustomProgressView ()

@property (nonatomic, retain) UIView *progressView;

@end

@implementation CustomProgressView

@synthesize progressColor,trackColor,progressView,progress;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.layer.cornerRadius = 5;
        // clipsToBounds is important to stop the progressView from covering the original view and its round corners
        self.clipsToBounds = YES;

        self.progressView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, frame.size.height)];
        [self addSubview:self.progressView];
    }

    return self;
}

-(void)setProgressColor:(UIColor *)theProgressColor {
    self.progressView.backgroundColor = theProgressColor;
    progressColor = theProgressColor;
}

-(void)setTrackColor:(UIColor *)theTrackColor {
    self.backgroundColor = theTrackColor;
    trackColor = theTrackColor;
}

-(void)setProgress:(float)theProgress {
    progress = theProgress;
    CGRect theFrame = self.progressView.frame;
    theFrame.size.width = self.frame.size.width * theProgress;
    self.progressView.frame = theFrame;
}
@end

Ответ 3

У меня был пользовательский UIProgressView с его собственным drawRect, обновляемым из фонового процесса. В iOS6 все работало в то время как в iOS7 индикатор прогресса просто не обновлялся.

Я добавил layoutSublayersOfLayer сразу после setProgress, как этот

[self.loadingProgress setProgress:pv.floatValue];
[self.loadingProgress layoutSublayersOfLayer:self.loadingProgress.layer];

и он работал как шарм.

Я надеюсь, что это поможет кому-то.

Ответ 4

Избегайте головной боли и используйте эту отличную библиотеку:

YLProgressBar

  • Скопируйте YLProgressBar.h и YLProgressBar.m из папки YLProgressBar.
  • #import "YLProgressBar.h" в файле (ых), который вы хотите использовать индикатор выполнения
  • Добавьте свой индикатор выполнения либо по коду, либо по xib
  • progressBar.type = YLProgressBarTypeRounded; progressBar.progressTintColor = [UIColor greenColor]; progressBar.stripesOrientation = YLProgressBarStripesOrientationVertical; progressBar.stripesDirection = YLProgressBarStripesDirectionLeft;
  • У вас есть хороший, полностью функциональный индикатор выполнения, который поддерживает ширину, высоту, модификации.