如何以编程方式使用自动布局添加自定义视图

Posted

技术标签:

【中文标题】如何以编程方式使用自动布局添加自定义视图【英文标题】:How to add custom view with autolayout programmatically 【发布时间】:2015-10-20 09:01:57 【问题描述】:

我的故事板有一个包含 UIScrollView 的视图控制器。我想在 viewController 中以编程方式向滚动视图添加一些自定义视图(每个视图将包含一个图像和标签)。我在情节提要中为 UIScrollView 设置了约束,但努力添加带有约束的自定义视图。我怎样才能做到这一点,以便它可以在所有设备(iPhone/iPad)上显示为相同?我尝试了下面的方法,但它似乎不起作用。

在我的 ViewController.m 中 -

#import "MainViewController.h"

#define DEFAULT_ROW_HEIGHT 50

@interface MainViewController ()

@property float topMarginFromUpperView;

@end

@implementation MainViewController

-(void) addCustomRowToView 
    self.topMarginFromUpperView += DEFAULT_ROW_HEIGHT + 10.0f;
    UIView *customRow = [[UIView alloc] initWithFrame:self.scrollView.bounds];
    customRow.backgroundColor = [UIColor redColor];
    [self.scrollView addSubview:customRow];

    customRow.translatesAutoresizingMaskIntoConstraints = NO;

    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:customRow attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeTop multiplier:1.0f constant:self.topMarginFromUpperView]];
    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:customRow attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:10.0f]];
    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:customRow attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:-10.0f]];
    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:customRow attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeHeight multiplier:0.1f constant:0.0f]];


- (void)viewDidLoad 
    [super viewDidLoad];

    self.topMarginFromUpperView = 0.0f;
    for (NSInteger i =0; i< 10; i++) 
        [self addCustomRowToView];
    


- (void)didReceiveMemoryWarning 
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


@end

已编辑:

仍在为约束设置而苦苦挣扎。由于无效约束,应用程序崩溃。尝试如下-

-(void) setConstraints:(UIView *)customRow 

    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:customRow attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeTop multiplier:1.0f constant:self.topMarginFromSuperView]];
    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:customRow attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:10.0f]];
    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:customRow attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:-10.0f]];
    [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:customRow attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeHeight multiplier:0.1f constant:0.0f]];


-(void) addCustomRowToView 
    UIView *customRow = [[UIView alloc]initWithFrame:CGRectMake(DEFAULT_PADDING, self.topMarginFromSuperView, self.view.bounds.size.width - 2*DEFAULT_PADDING, DEFAULT_ROW_HEIGHT)];
    customRow.backgroundColor = [UIColor redColor];
    customRow.translatesAutoresizingMaskIntoConstraints = NO;

    [self setConstraints:customRow];

    [self.scrollView addSubview:customRow];
    self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.topMarginFromSuperView + DEFAULT_ROW_HEIGHT);
    self.topMarginFromSuperView += DEFAULT_ROW_HEIGHT + DEFAULT_PADDING;


- (void)viewDidLoad 
    [super viewDidLoad];

    self.topMarginFromSuperView = 0.0f;
    //for (NSInteger i =0; i< 10; i++) 
        [self addCustomRowToView];
   // 
    

@end

【问题讨论】:

这个link 可以帮助你。 【参考方案1】:

这里是您的问题的解决方案:

 - (void)addCustomView

    UIView *lastView;
    for (int i = 0; i<10; i++)
    
        UIView *view = [[UIView alloc] init];
        view.backgroundColor = i%2 ? [UIColor redColor] : [UIColor greenColor];
        view.translatesAutoresizingMaskIntoConstraints = NO;
        [self.scrollView addSubview:view];
        [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[view]-10-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)]];
        [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeWidth multiplier:1 constant:-20.0]];

        if (i == 0)
        
            [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view(40)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)]];

        
        else
        
            [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[lastView(40)]-10-[view(40)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(lastView,view)]];
        
        lastView = view;
    
    [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[lastView(40)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(lastView)]];

【讨论】:

感谢您的帮助。不幸的是,您的解决方案对我不起作用。收到错误为“由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'无法解析约束格式:遇到名为“width”的度量,但在度量或视图字典中未指定值H:| [view(width)] | " 那么你需要用一个整数值来改变“width”/“height”。 @Nuibb 你再试一次吗? 抱歉回复晚了。它不适合我。实际上,对于不同的设备和不同的方向,自定义视图/行的宽度应该动态更改为左填充 10 和右填充 10。我不希望视图有任何固定宽度。此外,在您的情况下,滚动视图根本不滚动。我试过“H:|-10-[view]-10-|”用于水平视觉格式并设置滚动视图的内容大小以启用滚动,但对我没有任何作用。

以上是关于如何以编程方式使用自动布局添加自定义视图的主要内容,如果未能解决你的问题,请参考以下文章

使用堆栈视图和自动布局创建自定义 UITableViewCell

如何以编程方式在 UITableViewCell 中添加自定义视图?

多个自定义视图的自动布局问题

将完整的编程自定义视图添加到 ViewController。自动布局问题

以编程方式在活动视图顶部添加自定义视图

如何以编程方式将自定义 uiview 添加到视图控制器 SWIFT