我的需求非常笼统,我必须实现一个UIView子类,该子类将一个UIImageView分组(在屏幕上以x为中心,距顶部20 pt),以及一个带有说明的UILabel。
使用Interface Builder时,我没有遇到任何问题,但是由于我需要以编程方式进行制作,因此我照顾了技术和最佳实践。
到目前为止,我想出了这段代码,开始仅形象化图像。尽管这是非常基本的,但我无法理解为什么视图不能派生出正确的框架(如您从屏幕快照中所见),该框架应在图像视图的所有边缘上“偏移” 20个点。

这是我的子类:

标头

@interface ProgrammaticAutolayoutView : UIView

@property (nonatomic, strong) UIImageView *imageView;

@end

实现
#import "ProgrammaticAutolayoutView.h"

@implementation ProgrammaticAutolayoutView{

    BOOL _didUpdateConstraints;
}

- (instancetype)init
{
    return [self initWithFrame:CGRectZero];;
}

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

        _didUpdateConstraints = NO;

        _imageView = [UIImageView new];
        [_imageView setTranslatesAutoresizingMaskIntoConstraints: NO];

        [self addSubview: _imageView];
    }
    return self;
}

- (void) updateConstraints{

    if(!_didUpdateConstraints){
        [self setupConstraints];
    }

    [super updateConstraints];
}

- (void) setupConstraints{

    [self.imageView addConstraint:[NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:50]];

    [self.imageView addConstraint:[NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:50]];

    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:20.0]];

    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20.0]];

    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1.0 constant:20.0]];

    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:20.0]];

    _didUpdateConstraints = YES;
}

@end

这是我用来实例化和绘制此uiview子类的代码片段:
    - (void)viewDidLoad {
    [super viewDidLoad];

    ProgrammaticAutolayoutView *test = [[ProgrammaticAutolayoutView alloc] init];
    [test setTranslatesAutoresizingMaskIntoConstraints:NO];
    test.imageView.image = [UIImage imageNamed:@"dmy"];
    test.backgroundColor = [UIColor redColor];

    [self.view addSubview: test];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem: test attribute:NSLayoutAttributeCenterX relatedBy: NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem: test attribute:NSLayoutAttributeCenterY relatedBy: NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];

    [test setNeedsLayout];
    [test layoutIfNeeded];
}

我原本希望看到子视图与uiimageview的所有边缘偏移20个点,但是结果是完全不同的,我没有调试器日志或任何不一致的地方,显然我必须缺少一些非常基本的东西,但是到目前为止我没有不明白什么。

最佳答案

常数描述X和Y偏移量。您的4个约束条件是:

  • 将imageView的顶部放在红色视图
  • 下方(+ Y 20)20点
  • 将imageView的底部放置在红色视图
  • 下方(+ Y 20)20点以下
  • 将imageView的前端指向红色View
  • 的右侧(+ X 20)
  • 将imageView的尾端指向红色View
  • 的右侧(+ X 20)

    那就是你的照片所显示的。

    要使红色框框住图像,可以将两个常量设为负数:
    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:20.0]];
    
    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-20.0]];
    
    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1.0 constant:20.0]];
    
    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:-20.0]];
    

    切换底部约束和尾部约束中的项目顺序:
    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:20.0]];
    
    [self addConstraint:[NSLayoutConstraint constraintWithItem: self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.imageView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20.0]];
    
    [self addConstraint:[NSLayoutConstraint constraintWithItem: self.imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1.0 constant:20.0]];
    
    [self addConstraint:[NSLayoutConstraint constraintWithItem: self attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.imageView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:20.0]];
    

    新建议的约束条件为:
  • 将imageView的底部放在红色View
  • 上方(-Y 20)20点
  • 将imageView的尾端指向红色View
  • 的左侧(-X 20)


  • 将红色视图的底部放在imageView下方20点(+ Y 20)
  • 将红色View的尾端放在imageView
  • 的右侧(+ X 20)

    关于ios - 使用自动布局以 subview 实现uiview子类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30437029/

    10-10 11:52
    查看更多