子视图未与自动布局的 centerX 对齐

Subview not aligned to centerX with autolayout

我试图根据meter(白框)水平居中gradientLayerContainer,但它不起作用。但是,当我使用相同的方法根据 _mapArea 水平居中 meter 时,它起作用了。这真的让我很困惑。

    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];

您可能会发现一个更容易使用的选项是创建一个“渐变条”视图子class,并让它为您处理所有渐变布局。

使用此示例视图 class:

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

这个示例视图控制器:

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],
    ]];
    
}

渐变会自动填充 GradientBar 视图的框架:

如果框架发生变化 - 例如设备旋转 - 您无需执行任何操作...渐变将自动更新: