1

My storyboard has a single view controller containing a UIScrollView. I want to add some custom view (each view will contain a image & label) to the scrollview programmatically in the viewController. I have set constraints to the UIScrollView in the storyboard but struggling to add custom views with constraints. How can i do this so that it can be appeared as same for all the devices (iPhone/iPad) ? I tried like below but it does not seems to be working.

In My 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

EDITED :

Still struggling with constraint setting. App crashes due to invalid constraint. Tried as below -

-(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
Nuibb
  • 1,800
  • 2
  • 22
  • 36

1 Answers1

1

Here is solution for your problem:

 - (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)]];
}
  • Thanks for help. Unfortunately your solution does not working for me. Getting error as "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse constraint format: Encountered metric with name "width", but value was not specified in metrics or views dictionaries H:|[view(width)]| " – Nuibb Oct 20 '15 at 11:49
  • well you need to change "width"/ "height" with an integer value. – Nazire Aslan Oct 20 '15 at 12:04
  • @Nuibb did you try again? – Nazire Aslan Oct 20 '15 at 13:15
  • Sorry for late reply. It's not working for me. Actually the custom view/row's width should be changed dynamically with left padding by 10 and right padding by 10 for different devices and different orientation. I don't want any fixed width for the view. Moreover, in your case, the scrollview does not scrolling at all. I tried with "H:|-10-[view]-10-|" for horizontal visual format and set content size of scrollview for enabling scrolling but nothing is working for me. – Nuibb Oct 21 '15 at 10:05