簡體   English   中英

iOS:使用NSLayoutConstraint將對象堆疊在一起

[英]iOS: Stack objects on top of each other using NSLayoutConstraint

我想把幾個按鈕疊在一起,然后顯示/隱藏它們作為切換的方式。 (想想視頻播放器中的播放/暫停/重播按鈕)。

是否可以使用NSLayoutConstraint執行此操作?

或者,也許有更好的方法在iOS中創建一個多狀態按鈕?

這就是我嘗試過的,但是因為它將它們放在彼此旁邊,所以它們不起作用:

NSArray *constraints = [NSLayoutConstraint
  constraintsWithVisualFormat:@"|[_playButton][_pauseButton][_replayButton][_scrubber][_minimizeButton]|"
                      options:0
                      metrics:nil
                      views:viewsDictionary];

使用下面@dasdom的一些提示,我想出了以下內容:

NSArray *constraints = [NSLayoutConstraint
  constraintsWithVisualFormat:@"|[_pauseButton]-[_scrubber]-[_minimizeButton]|"
                      options:NSLayoutFormatAlignAllCenterY
                      metrics:nil
                      views:viewsDictionary];

[constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint
  constraintsWithVisualFormat:@"|[_playButton]"
                      options:NSLayoutFormatAlignAllCenterY
                      metrics:nil
                      views:viewsDictionary]];

[constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint
  constraintsWithVisualFormat:@"|[_replayButton]"
                      options:NSLayoutFormatAlignAllCenterY
                      metrics:nil
                        views:viewsDictionary]];

[self addConstraints:constraints];

哪個非常接近 - 水平間距是正確的,對於第一個規則中的項目(pauseButton,scrubber,最小化),它們垂直對齊,但播放和重放按鈕太高......好像后續的NSLayoutFormatAlignAllCenterY是被忽略了。

編輯2:這是我最終得到的最終代碼,比我想象的要多得多,但似乎效果很好:

NSDictionary *metrics = @{
    @"buttonPadding": @(kBarPaddingX)
};
// Align along Y center and set order, so scrubber stretches in the middle.
NSString *controlsVisualFormat =
  @"|-buttonPadding-[_playButton]-[_scrubber]-[_minimizeButton]-buttonPadding-|";
NSArray *constraints = [NSLayoutConstraint
  constraintsWithVisualFormat:controlsVisualFormat
                      options:NSLayoutFormatAlignAllCenterY
                      metrics:metrics
                      views:viewsDictionary];

// Set alignment of pauseButton and replayButton
constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint
  constraintsWithVisualFormat:@"|-buttonPadding-[_pauseButton]"
                      options:NSLayoutFormatAlignAllCenterY
                      metrics:metrics
                      views:viewsDictionary]];
constraints = [constraints arrayByAddingObjectsFromArray:[NSLayoutConstraint
  constraintsWithVisualFormat:@"|-buttonPadding-[_replayButton]"
                      options:NSLayoutFormatAlignAllCenterY
                      metrics:metrics
                        views:viewsDictionary]];

// Not sure why using NSLayoutFormatAlignAllCenterY above doesn't center the buttons vertically,
// so we need another set of constraints to center them vertically.
constraints = [constraints arrayByAddingObject:
  [NSLayoutConstraint constraintWithItem:_pauseButton
                               attribute:NSLayoutAttributeCenterY
                               relatedBy:NSLayoutRelationEqual
                                  toItem:_pauseButton.superview
                               attribute:NSLayoutAttributeCenterY
                              multiplier:1.0f
                                constant:0]];
constraints = [constraints arrayByAddingObject:
  [NSLayoutConstraint constraintWithItem:_replayButton
                               attribute:NSLayoutAttributeCenterY
                               relatedBy:NSLayoutRelationEqual
                                  toItem:_replayButton.superview
                               attribute:NSLayoutAttributeCenterY
                              multiplier:1.0f
                                constant:0]];

你可以嘗試使用

NSArray *constraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"|[_playButton(==_pauseButton)]"
                  options:0
                  metrics:nil
                  views:viewsDictionary];

constraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"V:|[_playButton(==_pauseButton)]"
                  options:0
                  metrics:nil
                  views:viewsDictionary];

[self addConstraint:[NSLayoutConstraint constraintWithItem:_playButton 
    attribute:NSLayoutAttributeCenterY 
    relatedBy:NSLayoutRelationEqual 
    toItem:_pauseButton 
    attribute:NSLayoutAttributeCenterY 
    multiplier:1.0f 
    constant:0.0f]];

[self addConstraint:[NSLayoutConstraint constraintWithItem:_playButton 
    attribute:NSLayoutAttributeCenterX 
    relatedBy:NSLayoutRelationEqual 
    toItem:_pauseButton 
    attribute:NSLayoutAttributeCenterX 
    multiplier:1.0f 
    constant:0.0f]];

這個答案解決了Edit2下的代碼。

你做了很好的工作來構建一個很好的水平行的各種按鈕,即_playButton - > _minimizeButton 但是,格式選項NSLayoutFormatAlignAllCenterY僅相對於所有其他按鈕垂直對齊每個按鈕。 您仍然沒有建立一個規則,將沿着垂直軸的按鈕行相對於行的容器視圖定位

由於所有按鈕已經相對於彼此垂直對齊,您所要做的就是向其中一個按鈕(任何按鈕)添加垂直軸類型約束。 這是一個假設的例子,它將播放按鈕頂部的40個點從容器視圖的頂部開始。 如果你想要一個更實際的例子,我需要更好地理解整體布局。

[[containerView addConstraint:[NSLayoutConstraint constraintWithItem:_playButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:containerView attribute:NSLayoutAttributeTop multiplier:1.0f constant:40.0f]];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM