0

Я хочу создать пользовательский бар для отображения определенного прогресса, который должен выглядеть примерно так:Создание градиент на основе UICollectionViewCell цвета фона

enter image description here

Итак, как вы можете видеть каждый бар имеет собственный градиент фон , Я хочу использовать для этого UICollectionView. Но проблема заключается в создании градиентного фона для каждой отдельной ячейки. Так возможно ли каким-то образом создать ОДИН базовый градиент для всего UICollectionView, а затем замаскировать его, чтобы быть видимым внутри UICollectionViewCell?

+0

Это слишком тяжелы, чтобы использовать UICollectionView просто для создания простого компонента. Я предлагаю вам подкласс UIView и рисовать CoreGraphics. – GeneCode

+0

Но мне нужно как-то обновить эти бары в ожидании прогресса в%. Таким образом, последний показывает текущий прогресс (например, емкость аккумулятора). И самое главное - я не мог полностью понять, с чего начать с CoreGraphics) –

+1

u может использовать слой градиента в качестве фона и маскировать его на прямоугольные прямоугольники, как показано на рисунке выше. –

ответ

1

Хорошо, вот пример, фон - это слой градиента с разными цветами, и вы можете создать слой маски, который будет отображаться только на прямоугольных фигурах, что дает иллюзию разных прямоугольных слоев, имеющих разные градиенты, вы можете играть с градиентом, чтобы получить желаемый эффект,

Сначала вы подкласс UIView или вы можете создать напрямую, лучше вы можете создать подкласс, как я делаю в примере

Obj-C

- (instancetype)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if(self) 
    { 
     [self createGreadient]; 
    } 
    return self; 
} 

//this create a grenadine with the rectangular mask layer 
- (void)createGreadient 
{ 
    UIColor *theColor = [UIColor redColor];//[[UIColor alloc] initWithRed:146.0/255.0 green:146.0/255.0 blue:146.0/255.0 alpha:1]; 
    CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init]; 
    gradientLayer.frame = self.bounds; 

    //u can add your own colours to get your requirement 
    gradientLayer.colors = [NSArray arrayWithObjects: 
          (id)[theColor CGColor], 
          (id)[[theColor colorWithAlphaComponent:0.7f] CGColor], 
          (id)[[theColor colorWithAlphaComponent:0.4f] CGColor], 
          (id)[[theColor colorWithAlphaComponent:0.3f] CGColor], 
          (id)[[theColor colorWithAlphaComponent:0.2f] CGColor], 
          (id)[[theColor colorWithAlphaComponent:0.1f] CGColor], 
          (id)[[UIColor clearColor] CGColor],nil]; 
    [self.layer addSublayer:gradientLayer]; 

    CAShapeLayer *layerMask = [[CAShapeLayer alloc] init]; 
    layerMask.frame = self.bounds; 
    UIBezierPath *rectangularMaskPath = [self getRectangularMaskPathForCount:5]; 
    layerMask.path = rectangularMaskPath.CGPath; 

    gradientLayer.mask = layerMask; 

} 

//this creates rectangular path, u can adjust the rectangular and u can 
//pass different number of count as the progress proceeds 
- (UIBezierPath *)getRectangularMaskPathForCount:(NSInteger)rectCount 
{ 
    UIBezierPath *path = [[UIBezierPath alloc] init]; 
    int i = 0; 
    for(;i <= rectCount; i++) 
    { 
     UIBezierPath *aPath; 
     CGRect aRect = CGRectMake(20+ (i * 20), 20, 10, 100); //set the rectangular position to your requirement 
     aPath = [UIBezierPath bezierPathWithRect:aRect]; 
     [path appendPath:aPath]; 
    } 
    return path; 
} 

быстры версия подкласс UIView и мимо кода ниже,

override init (frame : CGRect) { 
    super.init(frame : frame) 
    createGreadient() 
} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 



func createGreadient() 
{ 
    let color:UIColor = UIColor.red 
    let greadetLayer = CAGradientLayer.init() 

    greadetLayer.frame = self.bounds 
    greadetLayer.colors = [color.withAlphaComponent(0.8).cgColor,color.withAlphaComponent(0.7),color.withAlphaComponent(0.4).cgColor,color.withAlphaComponent(0.3).cgColor,color.withAlphaComponent(0.2),color.withAlphaComponent(0.1).cgColor] 

    self.layer .addSublayer(greadetLayer) 
    let rectangularMaskPath = self.creatrRectangularPathWithCount(countRect: 5) 
    let maskLayer:CAShapeLayer = CAShapeLayer() 
    maskLayer.frame = self.bounds 
    maskLayer.path = rectangularMaskPath.cgPath 
    greadetLayer.mask = maskLayer 

} 


func creatrRectangularPathWithCount(countRect:NSInteger) -> UIBezierPath { 
    let path : UIBezierPath = UIBezierPath() 
    for i in 0..<countRect { 
     let aPath = UIBezierPath.init(rect: CGRect(x: 20 + (i * 20), y:20, width: 10, height: 100)) 
     path.append(aPath) 
    } 
    return path 
} 

Вы можете использовать приведенные выше вид, как показано ниже, в ViewController

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 
    let customView:CustomView = CustomView(frame: CGRect(x: 20, y: 20, width: 300, height: 300)) 
    self.view.addSubview(customView) 

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