子视图未与自动布局的 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
视图的框架:
如果框架发生变化 - 例如设备旋转 - 您无需执行任何操作...渐变将自动更新:
我试图根据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
视图的框架:
如果框架发生变化 - 例如设备旋转 - 您无需执行任何操作...渐变将自动更新: