Próbowałem wyśrodkować gradientLayerContainer zgodnie z meter (białe pudełko) poziomo, ale nie działa. Jednakże, gdy wyśrodkuję meter zgodnie z _mapArea poziomo z tą samą metodą, którą działa. To naprawdę mnie mylą.

enter image description here

    UIView* meter = [[UIView alloc] init];
    [meter setTranslatesAutoresizingMaskIntoConstraints:NO];
    meter.backgroundColor = UIColor.whiteColor;
    
    [_mapArea addSubview:meter];
    [NSLayoutConstraint activateConstraints:@[
        [meter.widthAnchor constraintEqualToConstant:_mapArea.frame.size.width * 1],
        [meter.heightAnchor constraintEqualToConstant:60],
        
        [meter.centerXAnchor constraintEqualToAnchor:_mapArea.centerXAnchor],
        [meter.topAnchor constraintEqualToAnchor:_mapArea.topAnchor constant:16]
    ]];
    
    [meter layoutIfNeeded];
    
    // gradient bar
    CAGradientLayer* gradientLayer = [[CAGradientLayer alloc] init];
    gradientLayer.frame = CGRectMake(0, 0, meter.frame.size.width * 0.9, 30); 
    gradientLayer.colors = [NSArray arrayWithObjects:
                            (id)[UIColor clearColor].CGColor,
                            (id)[UIColor whiteColor].CGColor,
                            (id)[UIColor colorWithRed:0.19 green:0.3 blue:0.8 alpha:1.0].CGColor,
                            (id)[UIColor colorWithRed:0.73 green:0.23 blue:0.25 alpha:1.0].CGColor,
                            (id)[UIColor yellowColor].CGColor, nil];
    gradientLayer.locations = [NSArray arrayWithObjects:
                                [NSNumber numberWithFloat:0.0f],
                                [NSNumber numberWithFloat:0.01f],
                                [NSNumber numberWithFloat:0.1f],
                                [NSNumber numberWithFloat:0.5f],
                                [NSNumber numberWithFloat:1.0f],
                                nil];

    gradientLayer.startPoint = CGPointMake(0, 0.5);
    gradientLayer.endPoint = CGPointMake(1, 0.5);
    
    UIView* gradientLayerContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, gradientLayer.frame.size.width, gradientLayer.frame.size.height)];
    [gradientLayerContainer.layer addSublayer:gradientLayer];
    [gradientLayerContainer setTranslatesAutoresizingMaskIntoConstraints:NO];
        
    [meter addSubview: gradientLayerContainer];

    [NSLayoutConstraint activateConstraints:@[
        [gradientLayerContainer.centerXAnchor constraintEqualToAnchor:meter.centerXAnchor],
        [gradientLayerContainer.topAnchor constraintEqualToAnchor:meter.topAnchor constant:4]
    ]];
    

    [gradientLayerContainer layoutIfNeeded];

0
jonijeng 13 październik 2020, 13:54

1 odpowiedź

Najlepsza odpowiedź

Jedną z opcji, z którymi możesz znacznie łatwiej znaleźć, jest utworzenie podklasu "Gradient Bar" Widok podklasu i pozwól, aby obsłużyć cały układ gradientu dla Ciebie.

Korzystanie z tego przykładowego klasy klasy:

gradientBarview.h

//  GradientBarView.h
//  Created by Don Mag on 10/13/20.

#import <UIKit/UIKit.h>

@interface GradientBarView : UIView
@end

gradientBarview.m

//  GradientBarView.m
//  Created by Don Mag on 10/13/20.

#import "GradientBarView.h"

@implementation GradientBarView

+ (Class) layerClass{
    return [CAGradientLayer class];
}
- (instancetype)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        NSLog(@"init coder");
        [self commonInit];
    }
    return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        NSLog(@"init frame");
        [self commonInit];
    }
    return self;
}
- (instancetype)init
{
    self = [super init];
    if (self) {
        NSLog(@"init ");
        [self commonInit];
    }
    return self;
}

- (void)commonInit {
    
    CAGradientLayer *gradientLayer;
    gradientLayer = (CAGradientLayer *)[self layer];
    
    gradientLayer.colors = [NSArray arrayWithObjects:
                            (id)[UIColor clearColor].CGColor,
                            (id)[UIColor whiteColor].CGColor,
                            (id)[UIColor colorWithRed:0.19 green:0.3 blue:0.8 alpha:1.0].CGColor,
                            (id)[UIColor colorWithRed:0.73 green:0.23 blue:0.25 alpha:1.0].CGColor,
                            (id)[UIColor yellowColor].CGColor, nil];
    gradientLayer.locations = [NSArray arrayWithObjects:
                               [NSNumber numberWithFloat:0.0f],
                               [NSNumber numberWithFloat:0.01f],
                               [NSNumber numberWithFloat:0.1f],
                               [NSNumber numberWithFloat:0.5f],
                               [NSNumber numberWithFloat:1.0f],
                               nil];
    
    gradientLayer.startPoint = CGPointMake(0, 0.5);
    gradientLayer.endPoint = CGPointMake(1, 0.5);
    
}

@end

I ten przykładowy kontroler widoku:

exampleviewcontroller.h

//  ExampleViewController.h
//  Created by Don Mag on 10/13/20.

#import <UIKit/UIKit.h>

@interface ExampleViewController : UIViewController
@end

exampleviewcontroller.m

//  ExampleViewController.m
//  Created by Don Mag on 9/22/20.

#import "ExampleViewController.h"
#import "GradientBarView.h"

@implementation ExampleViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    UIView *meter = [UIView new];
    meter.backgroundColor = [UIColor whiteColor];
    
    GradientBarView *gradientBar = [GradientBarView new];

    meter.translatesAutoresizingMaskIntoConstraints = NO;
    gradientBar.translatesAutoresizingMaskIntoConstraints = NO;

    [meter addSubview:gradientBar];
    [self.view addSubview:meter];

    // respect safe area
    UILayoutGuide *g = [self.view safeAreaLayoutGuide];

    [NSLayoutConstraint activateConstraints:@[
        // meter Width: 90% of view width, Height: 60
        [meter.widthAnchor constraintEqualToAnchor:g.widthAnchor multiplier:0.9],
        [meter.heightAnchor constraintEqualToConstant:60],
        
        // meter Top: 16-pts from top of view, centered horizontally
        [meter.topAnchor constraintEqualToAnchor:g.topAnchor constant:16.0],
        [meter.centerXAnchor constraintEqualToAnchor:g.centerXAnchor],

        // gradient bar Width: 90% of meter width, Height 30
        [gradientBar.widthAnchor constraintEqualToAnchor:meter.widthAnchor multiplier:0.9],
        [gradientBar.heightAnchor constraintEqualToConstant:30.0],
        
        // gradient bar Top: 4-pts, centered horizontally
        [gradientBar.topAnchor constraintEqualToAnchor:meter.topAnchor constant:4.0],
        [gradientBar.centerXAnchor constraintEqualToAnchor:meter.centerXAnchor],
    ]];
    
}

Gradient automatycznie wypełnia ramę widoku GradientBar:

enter image description here

Jeśli zmieni się ramy - takie jak obrót urządzenia - nie musisz robić nic ... Gradient automatycznie aktualizuje:

enter image description here

1
DonMag 13 październik 2020, 15:26