2016-07-15 4 views
0

iOSプログラミングに慣れてきて、固定数の項目で多かれ少なかれautolayoutをマスターしました。 UILabelのタイトル、UILabelのサブタイトルがある場合は、制約のビジュアル形式は'V:|-[title]-10-[subtitle]-|'です。NSLayoutConstraintコードのサブビュー数が不明である

しかし、APIの応答に基づいてサブビューを動的に作成するとどうなりますか?たとえば、追加する必要があるサブビューは40件あります。もはや私は各サブビューをビジュアルフォーマットで指定し、それらを追跡するのは現実的ではありません。適切な方法は何ですか?

私は各サブビューを追加した後、前のビューに基づく制約をconstraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:と設定していると思います。それは行く道なのか、それとも良い方法がありますか?

答えて

1

それはなぜ地球上

私は視覚的な形式で、各サブビューを指定し、それらを追跡することはもう

現実的ではないではないのか?あなたはこれが何らかの「どちらか/あるいは」の状況だと思っているようです。視覚的な書式設定を使用して制約のコレクションを構築することはできません。法律では、 のすべてをビジュアルフォーマットに入力する必要があります。

レイアウトエンジンは、あなたの制約を形成するために使用したという表記を知らないか気にしません。制約は制約です!私は視覚的な書式設定を使用していますが、私は、私のように、時間としてそれを一の制約をやってる

var con = [NSLayoutConstraint]() 
    con.appendContentsOf(
     NSLayoutConstraint.constraintsWithVisualFormat(
      "H:|[sv]|", 
      options:[], metrics:nil, 
      views:["sv":sv])) 
    con.appendContentsOf(
     NSLayoutConstraint.constraintsWithVisualFormat(
      "V:|[sv]|", 
      options:[], metrics:nil, 
      views:["sv":sv])) 
    var previousLab : UILabel? = nil 
    for i in 0 ..< 30 { 
     let lab = UILabel() 
     // lab.backgroundColor = UIColor.redColor() 
     lab.translatesAutoresizingMaskIntoConstraints = false 
     lab.text = "This is label \(i+1)" 
     sv.addSubview(lab) 
     con.appendContentsOf(
      NSLayoutConstraint.constraintsWithVisualFormat(
       "H:|-(10)-[lab]", 
       options:[], metrics:nil, 
       views:["lab":lab])) 
     if previousLab == nil { // first one, pin to top 
      con.appendContentsOf(
       NSLayoutConstraint.constraintsWithVisualFormat(
        "V:|-(10)-[lab]", 
        options:[], metrics:nil, 
        views:["lab":lab])) 
     } else { // all others, pin to previous 
      con.appendContentsOf(
       NSLayoutConstraint.constraintsWithVisualFormat(
        "V:[prev]-(10)-[lab]", 
        options:[], metrics:nil, 
        views:["lab":lab, "prev":previousLab!])) 
     } 
     previousLab = lab 
    } 
    con.appendContentsOf(
     NSLayoutConstraint.constraintsWithVisualFormat(
      "V:[lab]-(10)-|", 
      options:[], metrics:nil, 
      views:["lab":previousLab!])) 
    NSLayoutConstraint.activateConstraints(con) 

は、私はスクロールビューとその内側の30枚のラベルのための制約を構築このコードを考えてみましょうビューを追加します(これはあなたが尋ねるものです)。

+0

ハ。今私は親切な気分を感じる:)ありがとう – egze

+0

スクロールビューに 'contentSize.height'を設定して実際にスクロールできるようにするには、最後のラベルをスクロールビューの下端に拘束する必要があることに注意してください。 –

+0

@robmayoffそれをした、ちょうど貼り付けを中断した – matt

0

いくつかのレイアウトを作成するためのより高いレベルのツールがあるため、答えは本当に必要なレイアウトによって異なります。

iOS 9からは、UIStackViewを使用してビューの行または列を管理できます。 By nesting stack views, you can easily make a grid of views.UIStackViewの紹介については、“Mysteries of Auto Layout, Part 1” from WWDC 2015を見て始めてください。コードですべてのレイアウトを行っている場合は、TZStackViewを使用できます。これは、iOS 7以降で動作するUIStackViewの再実装です。

UICollectionViewは、グリッド内または他の多くの配置でビューをレイアウトするための別のツールです。 UIStackViewよりも複雑ですが、使用方法を教えるための入門用資料がたくさんあります(“Introducing Collection Views” from WWDC 2012など)。

0

動的レイアウトエンジン(水平レイアウトと垂直レイアウト)を構築しました。

  1. ビューの配列を受け入れます。

  2. ビューをサブビューとしてコンテナに追加します。

  3. 次に、垂直方向と水平方向のビジュアルレイアウト文字列を動的に合成します。 (これは、v%pを使用して配置された各ビューの一意の "Object Address"文字列を生成します。
  4. viewDidLoadで[myView addControls:@ [view1、view2、view3]]を呼び出して、あなたのために。
  5. ここには、縦型レイアウトの一般的なレイアウトエンジンがあります。楽しい。

    @implementation UIView (VerticalLayout) 
    
    - (void)addControls:(NSArray*)controls 
        align:(VerticalAlignment)alignment 
        withHeight:(CGFloat)height 
        verticalPadding:(CGFloat)verticalPadding 
        horizontalPadding:(CGFloat)horizontalPadding 
        topPadding:(CGFloat)topPadding 
        bottomPadding:(CGFloat)bottomPadding 
        withWidth:(CGFloat)width 
    { 
        NSMutableDictionary* bindings = [[NSMutableDictionary alloc] init]; 
        NSDictionary *metrics = @{ 
         @"topPadding": @(topPadding), 
         @"bottomPadding": @(bottomPadding), 
         @"verticalPadding": @(verticalPadding), 
         @"horizontalPadding":@(horizontalPadding) }; 
    
        NSMutableString* verticalConstraint = [[NSMutableString alloc] initWithString:@"V:"]; 
        if (alignment == VerticalAlignTop || alignment == VerticalAlignStretchToFullHeight) { 
         [verticalConstraint appendString:@"|"]; 
        } 
    
        for (UIView* view in controls) { 
         BOOL isFirstView = [controls firstObject] == view; 
         BOOL isLastView = [controls lastObject] == view; 
    
         [self addSubview: view]; 
    
         // Add to vertical constraint string 
         NSString* viewName = [NSString stringWithFormat:@"v%p",view]; 
         [bindings setObject:view forKey:viewName]; 
    
         NSString* yLeadingPaddingString = @""; 
         NSString* yTrailingPadding = @""; 
         if (isFirstView && topPadding > 0) { 
          yLeadingPaddingString = @"-topPadding-"; 
         } 
         else if (!isFirstView && verticalPadding > 0) { 
          yLeadingPaddingString = @"-verticalPadding-"; 
         } 
    
         if (isLastView && bottomPadding > 0) { 
          yTrailingPadding = @"-bottomPadding-"; 
         } 
    
         [verticalConstraint appendFormat:@"%@[%@%@]%@", 
          yLeadingPaddingString, 
          viewName, 
          height > 0 ? [NSString stringWithFormat:@"(%f)", height] : @"", 
          yTrailingPadding]; 
    
         NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat: 
           [NSString stringWithFormat: @"H:|-horizontalPadding-[%@%@]%@|", 
           viewName, 
           (width > 0 ? [NSString stringWithFormat:@"(%lf)", width] : @""), 
           width > 0 ? @"-" : @"-horizontalPadding-"] 
          options:NSLayoutFormatDirectionLeadingToTrailing 
          metrics:metrics 
          views:bindings]; 
    
         // high priority, but not required. 
         for (NSLayoutConstraint* constraint in constraints) { 
          constraint.priority = 900; 
         } 
    
         // Add the horizontal constraint 
         [self addConstraints: constraints]; 
        } 
    
        if (alignment == VerticalAlignBottom || alignment == VerticalAlignStretchToFullHeight) { 
         [verticalConstraint appendString:@"|"]; 
        } 
    
        NSArray* constraints = [NSLayoutConstraint 
          constraintsWithVisualFormat:verticalConstraint 
          options:NSLayoutFormatAlignAllLeading 
          metrics:metrics 
          views:bindings]; 
        for (NSLayoutConstraint* constraint in constraints) { 
         constraint.priority = 900; 
        } 
    
        // Add the vertical constraints for all these views. 
        [self addConstraints:constraints]; 
    } 
    
関連する問題