2015-04-22 84 views
0

有人能告訴我,我做錯了什麼在這裏... - 釘住的UIScrollView到其容器視圖 - PIN所有子視圖上的UIScrollViewscrollView:如何用分頁創建一個純自動佈局滾動視圖?

閱讀蘋果的技術說明這件事後,我都嘗試混合方法和純汽車佈局方法。使用NIB的混合方法在分頁時工作很糟糕,它看起來像一個滾動視圖中的大圖,而不是分頁。

然後,我在代碼中創建了純自動佈局版本,UIScrollView作爲UIView的子視圖。這一次的觀點而來,於是UIImage的是巨大的,就像它的全尺寸:

//scroll view 
    if (self.scrollView == nil) 
    { 
     self.scrollView = [[UIScrollView alloc] initWithFrame:self.frame]; 

     self.scrollView.translatesAutoresizingMaskIntoConstraints = NO; 

     [self.scrollView setClipsToBounds:NO]; 
     [self.scrollView setPagingEnabled:YES]; 

     [self addSubview: self.scrollView]; 
     [self addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView(300)]|" 
               options:0 metrics:nil 
                views:@{@"scrollView":self.scrollView}]]; 
     [self addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView(300)]|" 
               options:0 metrics:nil 
                views:@{@"scrollView":self.scrollView}]]; 

-(void) createContentView 
 
{ 
 
    
 
    for (int i=0; i<self.pageImages.count; i++) { 
 
     
 
     UILabel* topLabel = [[UILabel alloc] init]; 
 
     topLabel.text = [NSString stringWithFormat:@"topLabel %d", i+1]; 
 
     [topLabel sizeToFit]; 
 
     
 
     [self.topLabelArray insertObject:topLabel atIndex:i]; 
 
     [self.scrollView addSubview:topLabel]; 
 
     topLabel.translatesAutoresizingMaskIntoConstraints = NO; 
 
     
 

 
     UILabel* bottomLabel = [[UILabel alloc] init]; 
 
     bottomLabel.text = [NSString stringWithFormat:@"bottomLabel %d", i+1]; 
 
     [bottomLabel sizeToFit]; 
 

 
     [self.bottomLabelArray insertObject:bottomLabel atIndex:i]; 
 
     [self.scrollView addSubview:bottomLabel]; 
 
     bottomLabel.translatesAutoresizingMaskIntoConstraints = NO; 
 

 
     UIButton* button = [[UIButton alloc] init]; 
 
     button.titleLabel.text = [NSString stringWithFormat:@"button %d", i+1]; 
 
     [button sizeToFit]; 
 

 
     [self.buttonArray insertObject:button atIndex:i]; 
 
     [self.scrollView addSubview:button]; 
 
     button.translatesAutoresizingMaskIntoConstraints = NO; 
 
     
 
     UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[self.pageImages objectAtIndex:i]]]; 
 
     
 
     imageView.frame = CGRectMake(0,0,200,200); 
 
     
 
     imageView.translatesAutoresizingMaskIntoConstraints = NO; 
 
     imageView.contentMode = UIViewContentModeScaleAspectFit; 
 
     
 
      [self.pageViews insertObject:imageView atIndex:i]; 
 
     
 
     [self.scrollView addSubview:imageView]; 
 

 
     NSDictionary* viewsDictionary = @{@"topLabel":topLabel, 
 
              @"bottomLabel":bottomLabel, 
 
              @"button": button, 
 
              @"imageView": imageView 
 
              }; 
 

 
     [self.scrollView addConstraints: 
 
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(10)-[topLabel]-(10)-[imageView]-(10)-[bottomLabel]-(10)-|" 
 
               options:0 metrics:nil 
 
                views:viewsDictionary]]; 
 
     [self.scrollView addConstraints: 
 
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button]-(10)-|" 
 
               options:0 metrics:nil 
 
                views:viewsDictionary]]; 
 
     
 
     if (i==0) 
 
     { 
 
      [self.scrollView addConstraints: 
 
      [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[topLabel]" 
 
               options:0 metrics:nil 
 
                 views:viewsDictionary]]; 
 
      
 
      [self.scrollView addConstraints: 
 
      [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[imageView]" 
 
                options:0 metrics:nil 
 
                 views:viewsDictionary]]; 
 
       [self.scrollView addConstraints: 
 
      [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[bottomLabel]-(10)-[button]" 
 
                options:0 metrics:nil 
 
                 views:viewsDictionary]]; 
 
     } 
 
     else if (i == self.pageImages.count) 
 
     { 
 
      [self.scrollView addConstraints: 
 
      [NSLayoutConstraint constraintsWithVisualFormat:@"H:-(10)-[topLabel]-(10)-|" 
 
                options:0 metrics:nil 
 
                 views:viewsDictionary]]; 
 
      [self.scrollView addConstraints: 
 
      [NSLayoutConstraint constraintsWithVisualFormat:@"H:-(10)-[imageView]-(10)-|" 
 
                options:0 metrics:nil 
 
                 views:viewsDictionary]]; 
 

 
      [self.scrollView addConstraints: 
 
      [NSLayoutConstraint constraintsWithVisualFormat:@"H:-(10)-[bottomLabel]-(10)-[button]-(10)-|" 
 
                options:0 metrics:nil 
 
                 views:viewsDictionary]]; 
 
     
 
     } 
 
     else 
 
     { 
 
      [self.scrollView addConstraints: 
 
      [NSLayoutConstraint constraintsWithVisualFormat:@"H:[prevTopLabel]-(10)-[topLabel]" 
 
                options:0 metrics:nil 
 
                 views:@{@"prevTopLabel": [self.topLabelArray objectAtIndex: i-1], 
 
                   @"topLabel": topLabel 
 
                    }]]; 
 
      
 
      [self.scrollView addConstraints: 
 
      [NSLayoutConstraint constraintsWithVisualFormat:@"H:[prevImageView]-(10)-[imageView]" 
 
                options:0 metrics:nil 
 
                 views:@{@"prevImageView": [self.pageViews objectAtIndex: i-1], 
 
                   @"imageView": imageView 
 
                   }]]; 
 
      
 
      [self.scrollView addConstraints: 
 
      [NSLayoutConstraint constraintsWithVisualFormat:@"H:[prevButton]-(10)-[bottomLabel]-(10)-[button]" 
 
                options:0 metrics:nil 
 
                 views:@{@"prevButton": [self.buttonArray objectAtIndex: i-1], 
 
                   @"button":button, 
 
                   @"bottomLabel": bottomLabel 
 
                   }]]; 
 
     } 
 
     [self.scrollView addConstraint:[NSLayoutConstraint 
 
            constraintWithItem:topLabel 
 
            attribute:NSLayoutAttributeCenterX 
 
            relatedBy:NSLayoutRelationEqual 
 
            toItem:imageView 
 
            attribute:NSLayoutAttributeCenterX 
 
            multiplier:1 
 
            constant:0.0]]; 
 
     
 
     [self.scrollView addConstraint:[NSLayoutConstraint 
 
          constraintWithItem:bottomLabel 
 
          attribute:NSLayoutAttributeCenterX 
 
          relatedBy:NSLayoutRelationEqual 
 
          toItem:imageView 
 
          attribute:NSLayoutAttributeCenterX 
 
          multiplier:0.8 
 
          constant:0.0]]; 
 
    
 
//  [self.scrollView addConstraint:[NSLayoutConstraint 
 
//  

回答

0

行,有什麼錯在這裏的幾件事情:

else if (i == self.pageImages.count)

此條款將永遠不會運行,因爲您的循環計數設置爲中斷i == self.pageImages.count -1,這裏for (int i=0; i<self.pageImages.count; i++)

下一頁

 [self.scrollView addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:-(10)-[topLabel]-(10)-|" 
               options:0 metrics:nil 
                views:viewsDictionary]]; 
     [self.scrollView addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:-(10)-[imageView]-(10)-|" 
               options:0 metrics:nil 
                views:viewsDictionary]]; 

     [self.scrollView addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:-(10)-[bottomLabel]-(10)-[button]-(10)-|" 
               options:0 metrics:nil 
                views:viewsDictionary]]; 

這些也將產生無效的制約,特別是@"H:-(10)-[bottomLabel]....沒有寄託最左側的約束任何東西。所有連接視圖的視覺格式字符串都需要以視圖開始或結束。子視圖([subview])或超級視圖(|)。爲了解決這個問題,你需要在循環中保留對前一頁標籤的引用,並將其添加到VFL字符串的開頭。像這樣

@"H:[prevBottomLabel]-(10)-[bottomLabel].... 

    prevBottomLabel = bottomLabel; 
    // Continue loop 

下一頁:

UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[self.pageImages objectAtIndex:i]]]; 

    imageView.frame = CGRectMake(0,0,200,200); 

    imageView.translatesAutoresizingMaskIntoConstraints = NO; 
    imageView.contentMode = UIViewContentModeScaleAspectFit; 

這將不具有期望的效果,因爲你不能手動設置幀,則接通自動佈局。目前,幀值被忽略,高度和寬度由圖像視圖的固有內容大小設置,這將是圖像的高度和寬度。如果你想設置的高度和寬度,你需要有約束做到這一點,像這樣:

[imageView addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:[imageView(200)]" 
               options:0 metrics:nil 
                views:viewsDictionary]]; 

    [imageView addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:[imageView(200)]" 
               options:0 metrics:nil 
                views:viewsDictionary]]; 

這應該給你一些指點,有可能是有其他的錯誤太多,但修復這些是個好地方開始。

+0

感謝您的解釋......它現在可以工作。我嘗試了不同的方法來使它工作,代碼有點混亂(和錯誤)。我認爲我遇到的最大問題是VFL沒有以UIView結尾。我會記下它。另一個是與imageview大小。使用自動佈局,它看起來像只能使用約束來設置大小。也注意到了。是否還有限制而不是幀設置滾動大小(即分頁大小)?設置scrollview框架在過去爲我工作。 – NSCoder

+0

我也有一個問題,如果你可以幫助我確認:使用分頁,滾動視圖預計每個單獨的頁面被包含在一個單獨的UIView?我從語義上知道它看起來比較乾淨,也可能是一種首選方式。但是,是否有必要添加五個UIViews,每個UIViews包含UIImageView,標籤和按鈕,作爲子視圖和頁面的滾動視圖? – NSCoder

+0

爲了您的第一條評論,我相信分頁大小是由滾動視圖框架的寬度定義的,因此它會捕捉到寬度的倍數。滾動大小被定義爲很大,因爲它需要滿足其內容的約束條件。您可以將此視爲推出可擴展滾動區域的滾動視圖內容。這就是爲什麼你必須在不間斷的線路上從邊到邊運行約束條件才能正常工作。 –