2015-07-02 61 views
1

我想通過自動佈局約束將編程創建的UIView添加到scrollView中。就像Android中的垂直線性佈局一樣。 (In objective c not swift)將編程創建的視圖垂直添加到滾動視圖中(iOS中的線性佈局)

我在故事板的視圖控制器裏面有scrollview。所以基本上我想在垂直佈局中創建並添加幾個視圖,並且沒有空間進入該滾動視圖。我想根據視圖高度動態設置滾動視圖的容器大小。

每個視圖內都有標籤,每個視圖需要根據文本大小動態設置其高度。但可能我需要稍後再談。

for (int i=0; i<10; i++) 
{ 
    UIView *viewOne = UIView.new; 
    [viewOne setTranslatesAutoresizingMaskIntoConstraints:NO]; 
    viewOne.backgroundColor = [UIColor redColor]; 
    NSDictionary *viewsDictionary = @{@"viewOne" : viewOne}; 
    NSDictionary *metricsDictionary = @{@"horizontalSpacing" : @10}; 

    [self.scrollview addSubview:viewOne]; 

    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-horizontalSpacing-[viewOne]-horizontalSpacing-|" 
                      options:NSLayoutFormatDirectionLeadingToTrailing 
                      metrics:metricsDictionary 
                       views:viewsDictionary]; 

    NSArray *const_Height = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[viewOne(50)]" 
                    options:0 
                    metrics:nil 
                     views:viewsDictionary]; 

    [viewOne addConstraints:const_Height]; 
    [self.scrollview addConstraints:horizontalConstraints]; 
} 

使用該代碼我可以添加視圖,但我需要添加一個下另一個。

回答

5

UIScrollView的上下文中使用AutoLayout的情況下,我會建議使用ContentView內部您的UIScrollView。只需將它們添加到ViewControllers視圖裏面的viewDidLoad函數中即可。

@interface YourViewController() 
@property (nonatomic, strong) UIScrollView *dataScrollView; 
@property (nonatomic, strong) UIView* contentView; 
@end 

@implementation YourViewController 
@synthesize dataScrollView, contentView; 

- (void) viewDidLoad { 
    [super viewDidLoad]; 

    dataScrollView = [[UIScrollView alloc] init]; 
    contentView = [[UIView alloc] init]; 

    // adding the Views programmatically to the hierarchy 
    [self.view addSubview:dataScrollView]; 
    [dataScrollView addSubview:contentView]; 

    // don't translate the AutoresizingMask into constraints 
    dataScrollView.translatesAutoresizingMaskIntoConstraints = NO; 
    contentView.translatesAutoresizingMaskIntoConstraints = NO; 

    // backgroundColor as you wish? 
    dataScrollView.backgroundColor = [UIColor clearColor]; 
    contentView.backgroundColor = [UIColor clearColor]; 

    [dataScrollView setScrollEnabled:YES]; 
    [dataScrollView setAlwaysBounceVertical:YES]; 

    NSDictionary* viewsDictionary = NSDictionaryOfVariableBindings(dataScrollView, contentView); 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[dataScrollView]|" options:0 metrics: 0 views:viewsDictionary]]; 
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[dataScrollView]|" options:0 metrics: 0 views:viewsDictionary]]; 
    [dataScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView(==dataScrollView)]|" options:0 metrics: 0 views:viewsDictionary]]; 
    [dataScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics: 0 views:viewsDictionary]]; 

    // see below 
    // [self setUpViews]; 
} 

此代碼將做一個單一的視圖的技巧。將您需要的視圖添加爲子視圖到contentView並設置約束。

- (void) setUpViews { 
    UILabel* testLabel = [[UILabel alloc] init]; 
    [testLabel setText:@"Lorem Ipsum"]; 
    testLabel.translatesAutoresizingMaskIntoConstraints = NO; 
    [contentView addSubview: testLabel]; 

    // clean up your code with this metrics Dictionary 
    NSDictionary *metrics = @{@"margintop": @40, 
          @"marginleft": @10, 
          @"marginright": @10, 
          @"marginbottom": @20} 

    // the Views we want to layout with Constraints 
    NSDictionary *viewsDictionary = @{ 
            @"contentView":contentView, 
            @"dataScrollView":dataScrollView, 
            @"testLabel": testLabel} 

    // Horizontal (testlabel) 
    [contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-marginleft-[testLabel]-marginright-|" options:0 metrics: metrics views:viewsDictionary]]; 
    // Vertical 
    [contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-margintop-[testLabel]-marginbottom-|" options:0 metrics: metrics views:viewsDictionary]]; 
} 

參考您在for循環中添加多個視圖的問題,有很多可能的方法。這可能是與constraintsWithVisualFormat最簡單的解決方案。

- (void) setUpViews { 
    NSDictionary *metrics = @{@"margintop": @40, 
          @"marginleft": @10, 
          @"marginright": @10, 
          @"marginbottom": @20, 
          }; 
    // Alsways like to have contentView and DataScrollView here 
    NSMutableDictionary* dictViews = [[NSMutableDictionary alloc] initWithDictionary:@{@"contentView":contentView, 
                        @"dataScrollView":dataScrollView}]; 

    // Basic Leading-String for Vertical Constraints 
    NSString* verticalConstraintsString = @"V:|-margintop-"; 
    for (NSUInteger index = 0; index < 10; index++) { 
     // Do your Magic here & add your View 
     UILabel* testLabel = [[UILabel alloc] init]; 
     [testLabel setText:@"Lorem Ipsum"]; 
     testLabel.translatesAutoresizingMaskIntoConstraints = NO; 
     [contentView addSubview: testLabel]; 

     // Add to global Mutable Views-Dictionary dictViews 
     [dictViews setObject:testLabel forKey:[NSString stringWithFormat:@"testLabel%lu", (unsigned long)index]]; 
     // add "[testlabel1]" to the vertical Constraints 
     verticalConstraintsString = [NSString stringWithFormat:@"%@[testLabel%lu]-", verticalConstraintsString, (unsigned long)index]; 
     // Add Horizontal Constraints 
     [contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"H:|-marginleft-[testLabel%lu]-marginright-|", (unsigned long)index] options:0 metrics: metrics views:@{@"testLabel-%lu":testLabel}]]; 
    } 

    // Trailing-String 
    verticalConstraintsString = [NSString stringWithFormat:@"%@marginbottom-|", verticalConstraintsString]; 
    NSDictionary *viewsDictionary = [[NSDictionary alloc] initWithDictionary:dictViews]; 

    // finally adding the vertical Constraints 
    [contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalConstraintsString options:0 metrics: metrics views:viewsDictionary]]; 
} 

我希望這會幫助您獲得正確的視圖。

+0

謝謝你的回答,它幫助了很多。但我也想在循環中創建這些視圖。那麼我怎樣才能相互制約呢? 在你的例子中,我怎樣才能在循環中創建testLabel。使用這段代碼,它會將每個testLabel添加到舊版本的頂部。因爲它們都對頂部佈局有相同的約束。 –

+0

我已經更新了我的答案,並試圖解決您的問題。 – cr0ss

+1

謝謝你解決了我的問題。我將testLabel-%lu更改爲testLabel%lu​​。工作像一個魅力:) –

相關問題