针对不同方向的不同自动布局约束集

时间:2014-05-20 23:38:57

标签: ios cocoa-touch autolayout nslayoutconstraint

我见过类似的post,但它并不接近我的案例

所以我有不同方向的不同屏幕布局。应用程序正在使用故事板。 为了更好地理解,我附上了UI草图的照片 UI Sketch

正如您所看到的,有一个TableView和一个工具栏(一个自定义的)。工具栏包含2个标签和一个按钮。

所以肖像限制是:

  • 工具栏高度80pts
  • 工具栏尾随和前导空格== 0
  • TableView的导航栏顶部空间== 0
  • TableView的工具栏底部空间= 0
  • Tableview' s =工具栏宽度
  • 标签在工具栏中垂直居中,具有固定的尺寸和左右固定的距离
  • 按钮具有固定大小并位于工具栏
  • 中心

景观限制完全不同:

  • 工具栏宽度80pts
  • 工具栏顶部(来自导航栏)和底部空间== 0
  • 工具栏尾随空格== 0
  • TableView的领先空间== 0
  • TableView的工具栏尾随空格= 0
  • Tableview'的高度==工具栏宽度
  • 标签在工具栏中水平居中,具有固定的大小和从顶部和底部固定的距离
  • 按钮具有固定大小并位于工具栏
  • 中心

我尝试从故事板中删除所有约束并以编程方式添加它们。但Xcode会在编译过程中自动添加它们。我试图删除根视图中的所有约束,但可能我没有正确浏览所有视图树,因为几个约束都没有被删除。

您是否知道如何以适当的方式实施?

这是我第一次使用自动布局体验,并不像我预期的那么容易。

这里我的解决方案不起作用(因为Xcode在编译期间添加了一些约束)

// Those properties store all constraints for portrait and landscape modes
@property (nonatomic, strong) NSArray *portraitConstraints;
@property (nonatomic, strong) NSArray *landscapeConstraints;

-(void)updateViewConstraints {
    [super updateViewConstraints];

    BOOL layoutIsPortrait = UIDeviceOrientationIsPortrait(self.interfaceOrientation);

    if (layoutIsPortrait) {
        for (NSLayoutConstraint *constraint in self.landscapeConstraints)
            [constraint remove];

        for (NSLayoutConstraint *constraint in self.portraitConstraints)
            [constraint install];
    } else {
        for (NSLayoutConstraint *constraint in self.portraitConstraints)
            [constraint remove];

        for (NSLayoutConstraint *constraint in self.landscapeConstraints)
            [constraint install];
    }

}

- (NSArray *)portraitConstraints {
    if (!_portraitConstraints) {
        UIView *mainTable = self.myTableView;
        UIView *toolbar = self.toolbarView;
        UIView *firstLabel = self.firstLabel;
        UIView *secondLabel = self.secondLabel;
        UIView *bigButton = self.bigButton;
        UIView *navBar = self.navigationController.navigationBar;

        NSDictionary *views = NSDictionaryOfVariableBindings(mainTable,toolbar,firstLabel,secondLabel,bigButton,navBar);

        NSMutableArray *constraints = [NSMutableArray array];
        [constraints addObjectsFromArray:[NSLayoutConstraint
                                          constraintsWithVisualFormat:@"V:[toolbar(==80)]|"
                                          options:0
                                          metrics:nil
                                          views:views]];
        [constraints addObjectsFromArray:[NSLayoutConstraint
                                          constraintsWithVisualFormat:@"V:[navBar][mainTable][toolbar]|"
                                          options:0
                                          metrics:nil
                                          views:views]];
        // MORE AND MORE CONSTRAINTS ADDED HERE

        _portraitConstraints = constraints;
    }
    return _portraitConstraints;
}

1 个答案:

答案 0 :(得分:2)

您使用的方法当然是可行的,但会涉及相当多的代码来获取您正在寻找的布局。更简单的方法是删除故事板中的控制器视图(如果需要,可以将其复制并粘贴到xib文件中),而是创建视图,每个视图用于纵向和横向,一个xib文件。您可以在那里完成所有约束设置,只需在代码中的两个视图之间切换。您可以在一个xib文件中创建两个视图 - 我首先创建了一个肖像,因此它将是您从加载笔尖返回的数组中的第一个对象。

@interface ViewController ()
@property (strong,nonatomic) UIView *pView;;
@property (strong,nonatomic) UIView *lView;
@property (strong,nonatomic) UILabel *leftLabel;
@property (strong,nonatomic) UILabel *rightLabel;
@end

@implementation ViewController

- (void)loadView {
    NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"PortraitAndLandscapeViews" owner:self options:nil];
    self.pView = views[0];
    self.lView = views[1];
    self.view = self.pView;
}



-(void)viewWillLayoutSubviews {
    BOOL layoutIsPortrait = UIDeviceOrientationIsPortrait(self.interfaceOrientation);
    if (layoutIsPortrait) {
        self.view = self.pView;
        self.leftLabel = [self.view viewWithTag:11];
        self.rightLabel = [self.view viewWithTag:12];
    }else{
        self.view = self.lView;
        self.leftLabel = [self.view viewWithTag:21];
        self.rightLabel = [self.view viewWithTag:22];
    }
}