【问题标题】:Autolayout Constraints from column to row从列到行的自动布局约束
【发布时间】:2014-07-14 03:22:16
【问题描述】:

简化我的示例,假设我在基本视图控制器上有三个正方形。在纵向模式下,这些正方形相互堆叠,垂直间距为 20 像素左右。所以是这样的:

X
X
X

在横向模式下,第 3 个 X 会被切断,所以我想让它们看起来像这样:

XXX

换句话说,让底部的出现并紧挨着顶部(每个之间的水平间距为 20 像素左右)。

用自动布局、约束和大小类做这样的事情的方法是什么?我是否以编程方式删除并重新添加约束?只是从整体的角度很好奇如何实现这样的目标。

谢谢!

【问题讨论】:

标签: ios swift autolayout


【解决方案1】:

可以使用NSLayoutConstraint的优先级

Auto Layout 设置具有更高约束优先级的视图。

肖像

将方形视图的前导和顶部空间约束的优先级设置为低值(750 或低于 1000)。默认优先级值为 1000。

在 Interface Builder 中,您可以在 Attribute Inspector 中设置优先级。

横向

在代码中为横向模式创建约束。

约束应该比肖像具有更高的优先级。将约束保留在数组中,并在 UIViewController 的 viewWillLayoutSubviews 方法中添加或删除约束。

下面的测试代码。

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *view1; // square 1
@property (weak, nonatomic) IBOutlet UIView *view2; // square 2
@property (weak, nonatomic) IBOutlet UIView *view3; // square 3 

@end    

@implementation ViewController{

        NSMutableArray *_constraintsList;

    }

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.


        _constraintsList = [NSMutableArray new];


        // constraints for Landscape mode  
        // this constraints has 1000 priority. (default value) 
        // please modify offset value (20 or 40) to match your case. 

        NSDictionary *views = @{@"view1": self.view1, @"view2": self.view2,@"view3": self.view3};

        [_constraintsList addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[view1]-20-[view2]-20-[view3]"
                                                                                      options:0 metrics:nil
                                                                                        views:views]];
        [_constraintsList addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-40-[view2]" options:0 metrics:nil views:views]];


         [_constraintsList addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-40-[view3]" options:0 metrics:nil views:views]];


    }



    -(void)viewWillLayoutSubviews{

        [super viewWillLayoutSubviews];


        UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;

        if(currentOrientation == UIInterfaceOrientationPortrait){

            // in portrait mode. 
            // new constraints is not necessary. 
            [self.view removeConstraints:_constraintsList];


        }else if(currentOrientation == UIInterfaceOrientationLandscapeLeft){

            // for landscape mode
            // add new constraints. then auto layout adjust view to fit new higher constraints 
            [self.view addConstraints:_constraintsList];


        }

    }

【讨论】:

  • 有趣 - 所以这个想法是设置/限制它通常应该看起来的方式,具有较低的优先级,然后如果它处于横向模式,基本上添加具有更高优先级的新约束,它应该遵守新的约束?我可能应该查一下,但 @"V:|-40-[view2]" 有什么作用?我想 V 代表垂直,第一个元素和第二个元素之间的间距是 40 像素吗?
  • 是的。你知道我说什么。 @"v:|-40-[view2]" 只是示例代码。我只是想告诉你,你需要添加 square2 和 square3 的垂直约束。最好将 square2 和 square3 的垂直约束设置为等于 square1 的垂直中心。
  • 谢谢 - 嘿,只是出于好奇,(不是说某人更正确,等等,只是对您的意见感兴趣)您如何看待这个人的所作所为?他只使用情节提要:github.com/yas375/ExampleApp/tree/… 源帖子来自:stackoverflow.com/questions/19364430/… 你会说这是一个不太强大的解决方案吗?或者只是实现我所说的另一种方式?感谢您的帮助!
  • 我忘了这个。 @v:|-40-[view2]。 v 表示垂直。 |表示 view2 的超级视图。在我的测试用例中,它是 uiviewcontroller 的视图。我在界面生成器中的视图控制器视图中添加了方形视图。 40 表示 view2 的父视图和 view2 之间的 y 偏移量。
  • @user3379785 我已经检查了您链接的解决方案。我认为这是一个很好的解决方案,但有点难以理解程序员的意图。在您的情况下,正方形之间的关系对于绘制视图很重要。无需知道横向模式的屏幕尺寸即可计算方格位置。但在情节提要的情况下,您应该知道横向模式的大小来计算它。供您参考,使用优先级的解决方案对于自动布局中的视图动画也很有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
  • 2012-10-07
  • 2015-04-06
  • 2016-07-30
相关资源
最近更新 更多