如何使用自动布局故事板实现30个按钮网格?

时间:2015-05-24 03:42:38

标签: ios xcode autolayout xcode-storyboard

所以我使用了12按钮(4x3)按钮网格。

我希望所有的按钮尺寸相同,相同的距离在彼此的上方和侧面,并且整个网格要在设备上居中,如下所示:

my UI

问题是,当我构建项目时,它看起来像混乱。

我可以正确定位分段控件,分数或重置按钮,但网格只会让所有内容混乱。

我一直在使用中间工具在网格上设置约束,这对12个按钮网格工作正常:

constraint editor

但是,使用它只会创建无法通过xcode解析的无限冲突约束。

我是iOS的新手,可能会遗漏一些简单的东西,但我一直尽力在这里尽可能地匹配蓝色自动建议的行。

感谢您的任何建议。

2 个答案:

答案 0 :(得分:4)

使用带有UICollectionViewFlowLayout的UICollectionView并让流布局为您创建网格会更简单。

但即使你不打算这样做,我的建议仍然是:不要在Xcode / Interface Builder中设置它;在代码中创建整个网格(以及约束,如果你想要它们)。它更简单(更有趣,更无聊,当然,更不容易出错)。

答案 1 :(得分:2)

1。)不是在界面构建器中设置每个按钮,而是创建整个网格应该适合的容器(UIView)。将constraints添加到该容器中,以了解如何扩展和缩小屏幕大小。

2.。)将容器UIView链接到您的.h视图控制器类,并将其命名为gridContainer或其他。

3。)在.h类中创建一个属性:

@property (strong, nonatomic) NSMutableArray *twoDimensionalArrayContainingRowsOfCardButtons;

4.)然后:

- (void)viewDidLoad {

    // other stuff you're doing to set up your app
    self.twoDimensionalArrayContainingRowsOfCardButtons = [NSMutableArray new];

    //Do this inside the main thread to make sure all your other views are laid out before this starts
    //Sometimes when you do layout stuff before the rest of the view is set up from Interface Builder you will get weird results.
    dispatch_async(dispatch_get_main_queue(), ^{
        [self createTwoMentionalArrayHoldingCardButtons];
        [self displayCardGrid];
    }); 


}

- (void)createTwoMentionalArrayHoldingCardButtons {
    NSMutableArray *arrayWithRowsOfButtons= [NSMutableArray new];
    for (int x = 0; x < 6; x++) {
        NSMutableArray *arrayOfButtonsAtRowX = [NSMutableArray new];
        for (int i = 0; i < 6; i++) {
           CGRect rect = self.gridContainer.bounds;
           CGSize cellSize = CGSizeMake(rect.size.width / 6, rect.size.height / 6);
           UIButton *buttonInColumnI = [UIButton alloc] initWithFrame:CGRectMake(cellSize.width * i, cellSize.height * x, cellSize.width, cellSize.height);
           [buttonInColumnI setImage:[UIImage imageNamed:@"yourCardImage"] forState:UIControlStateNormal];
           [buttonInColumnI addTarget:self action:@selector(yourButtonAction:) forControlEvents:UIControlEventTouchUpInside];
           [arrayOfButtonsAtRowX addObject:buttonInColumnI];
        } 
        [arrayOfRowsOfButtons addObject:arrayOfButtonsAtRowX];
    }

    self.twoDimensionalArrayContainingRowsOfCardButtons = arrayWithRowsOfButtons;
}

- (void)displayCardGrid {
    for (int x = 0; x < self.twoDimensionalArrayContainingRowsOfCardButtons.count; x++) {
        NSMutableArray *arrayOfButtonsAtColumnsAtRowX = self.twoDimensionalArrayContainingRowsOfCardButtons[x];
        for (int i = 0; i < arrayOfButtonsAtColumnsAtRowX.count; i++) {
            UIButton *buttonAtColumnI = arrayOfButtonsAtColumnsAtRowX[i];
            [self.gridContainer addSubview:buttonAtColumnI];
        }
    }
}

- (void)yourButtonAction:(UIButton *)tappedCard {
    //To swap the card image on your tapped button
    for (int x = 0; x < self.twoDimensionalArrayContainingRowsOfCardButtons.count; x++) {
        NSMutableArray *arrayOfButtonsAtColumnsAtRowX = self.twoDimensionalArrayContainingRowsOfCardButtons[x];
        for (int i = 0; i < arrayOfButtonsAtColumnsAtRowX.count; i++) {
            UIButton *buttonAtColumnI = arrayOfButtonsAtColumnsAtRowX[i];
            if (tappedCard == buttonAtColumnI) {
                int row = x;
                int column = i;
                //Now you can save that the user has tapped something at this row and column.
                //While you're here, you can update the card image.
                [tappedCard setImage:[UIImage imageNamed:@"CardExposedImage"];
            }
        }
    }
}

我在这里写完所有内容而不运行它,所以希望这对你有用。结束了比预期更多的行。

编辑:忘记添加我将卡片按钮的构建分开并显示它们,以便您可以单独调用显示方法。使用该属性,您还拥有所有卡的保留源,因此您可以根据需要从阵列中取出它们并根据需要更改所需的内容。