一、之前,我们已经把“待选项”按钮,创建好了,但是唯一的问题是,坐标都是一样的,所以都显示在一起了 1.下面,我们来设置一下,这些“待选项”按钮的坐标, 现在,“待选项”按钮的坐标,是不是都在同一个位置啊, 回忆一下,这个待选项按钮,是怎么生成的, 首先,是在点击下一题,那个nextQuestion,那个方法里面, 1)第一步,获取当前我们这个问题对应的待选项options中那个数组吧, 2)第二步,获取那个数组以后,循环这个数组里面每一个文字,只要有一个文字,就创建一个按钮, 3)第三步,然后设置按钮的背景图,文字内容,文字颜色,都设置好以后,设置好坐标,最后是不是就显示进来了, 因为我们上午设置的每一个按钮的大小,都是35,并且,每一个按钮对应的frame都是一样的, 找到我们这个nextQuestion方法,里面有一个makeOptionsButton方法,按住control键,点击这个方法,转到它的定义,然后看咱们这个makeOptionsButton方法: - (void)makeOptionsButton:(TestQuestion *)model{ //1.清除待选按钮的view中的所有子控件 [self.optionsView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; //2.获取当前题目的待选文字的数组 NSArray *words = model.options; //3.根据待选文字循环来创建按钮 for(int I=0;i<words.count;i++)} //创建一个按钮 UIButton *btnOpt = [[UIButton alloc] init]; //设置按钮背景 [btnOpt setBackgroundImage:[UIImage imageNamed:@“btn_option”] forState:UIControlStateNormal]; [btnOpt setBackgroundImage:[UIImage imageNamed:@“btn_option_highlighted”] forState:UIControlStateHighlighted]; //设置按钮文字 [btnOpt setTitle:words[I]; forState:UIControlStateNormal]; //设置文字颜色为黑色 [btnOpt setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; //设置按钮frame btnOpt.frame = CGRectMake(0,0,35,35); //把按钮添加到optionsView中 [self.optionsView addSubviews:btnOpt]; } 以上就是我们之前写的makeOptionsButton方法的所有内容吧, frame都写的是0,0,所以,它们的坐标都是指向同一个位置吧, 虽然生成了很多待选按钮,但是它们的坐标都是0,0这个位置,所以是重复了,重叠了,看不到, 那么,接下来,我们要做的第一件事情,就是计算每一个待选按钮的frame,X,和,Y,让它们都横向,排开, 我们先分析一下我们这个示例程序, 整体这个红框,这是一个view,这个view,我们看一下,还是, 1)我们先声明一个变量,来告诉我们这个程序,一行要显示多少个这个按钮吧, 现在我们假设一行显示几个,7个吧, 一行假设显示7个, 我们这个变量,就是一个7, 2)然后,我们看一下,我们指定每一个按钮的宽和高,都是35,同时,指定每一个之间的间距,假设还是10,可以吧, 那么这样的话,每一个间距如果是10的话,两边儿这个距离,是不是就可以动态算出来了, 这个距离怎么算, 总的这个宽度 - 7 * 每一个的这个宽度 - 然后再减去,一共是一行7个单元格,每个单元格间距,有几个间距,是不是6个间距,这样的话,减去 10 * 6 , 是不是6个间距,剩下就是这两边的这个距离: 好,这两个边的这个距离,是不是除以2,就是一个边的距离, 这样的话,就算出marginLeft,这个值了, 算出这个值以后,每一个单元格的X坐标,就是用当前的marginLeft,加上几倍的这个(宽度 + margin)吧, 这个几倍的,指的就是当前这个单元格,所在的列的索引是多少,就是多少倍的, 然后,Y值的话,就是用这个marginTop,因为是紧贴住这个view的上边缘,所以说,marginTop就是0,用0 ,加上当前它在第几行,比如说这是在第0行,那么就是0倍的,一个高度 + margin,这是在第1行,就是1倍的这个高度 + margin,我们还是这个思路: 1)第一步,指定一个按钮的高和宽, 2)第二步,给它一个间距, 3)第三步,算出marginLeft那个值, 4)第四步,然后就可以根据公式,计算坐标了, 好,我们继续,我们这里看一下,还是生成option按钮的这么一个循环: - (void)makeOptionsButton:(TestQuestion *)model{ //1.清除带选按钮的view中的所有子控件 [self.optionsView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; //2.获取当前题目的待选文字的数组 NSArray *words = model.options; //3.根据待选文字循环来创建按钮 for(int i = 0 ; i < words.count; i++){ //创建一个按钮 UIButton *btnOpt = [[UIButton alloc ] init ] ; //设置按钮背景 [btnOpt setBackgroundImage:[UIImage imageNamed:@“btn_option”] forState:UIControlStateNormal]; [btnOpt setBackgroundImage:[UIImage imageNamed:@"btn_option_highlighted] forState:UIControlStateHighlighted]; //设置按钮文字 [btnOpt setTitle:words[i] forState:UIControlStateNormal]; //设置文字颜色为黑色 [btnOpt setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; //设置按钮frame btnOpt.frame = CGRectMake(0,0,35,35); //把按钮添加到optionsView中 [self.optionsView addSubviews:btnOpt]; } 好,这就是我们这个动态生成待选项按钮之前的代码,我们把计算坐标那些,都写在for循环的外面, //3.根据待选文字循环来创建按钮 //指定每个待选按钮的大小 CGFloat optionW = 35; CGFloat optionH = 35; //指定每个按钮之间的间距 CGFloat margin = 10; //指定每行有多少个按钮 int columns = 7; //计算出每行第一个按钮距离左边的距离 CGFloat marginLeft = (self.optionsView.frame.size.width - columns * optionW - (columns - 1) * margin) * 0.5; //好了,这样我们就有了这个marginLeft这个值了,接下来,我们就可以在for循环里面,计算出每一个按钮的坐标了, //但是,每一个按钮的坐标,我们首先要计算出,当前这个按钮是在索引第几的列,这个“小”字的索引,是不是0,1,2,索引为2的列啊,索引为为2的这一列,首先要计算出它所在的索引吧,列索引,然后还要计算出它所在的行索引,索引为0,1,索引为1这一行吧,计算出列和行的索引以后,接下来,用列和行的索引,就能算出它的坐标来了,好,接下来,在for循环的里面: //设置文字颜色为黑色 [btnOpt setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; //计算当前按钮的列的索引和行的索引, int colIdx = i % columns; int rowIdx = i / columns; CGFloat optionX = marginLeft + colIdx * (optionW + margin); CGFloat optionY = 0 + rowIdx * (optionH + margin); //设置按钮frame btnOpt.frame = CGRectMake(optionX , optionY , optionW , optionH); //把按钮添加到optionView中 [self.optionView addSubview:btnOpt]; } 运行一下看看,这样的话,这个值是不是过来了, 注意看,这个值,中间这个间距,和两边的间距,一样吗,是不是不一样啊 中间这个间距,是不是10,两边这个间距,是我们动态算出来的, 比如说,把这个columns改成5 int columns = 5; 每一行有5个,再运行,是不是变成这个效果了,是不是两边的间距,是不是都是活的啊, 这是我们这种算法,和那个九宫格的小区别, ok,但是我们这里就显示7个, 这个算出来以后,接下来我们是不是,动态,每点下一题的时候,这个答案的按钮,和我们这个待选按钮,是不是都生成好了吧,接下来,这些都生成好了以后,紧接着我们就是应该实现点击某一个待选项按钮的时候,是不是把它显示上来,点击某一个字,把它显示上来,这是我们接下来实现另外一个功能, 好了,这就是我们动态生成待选项按钮的坐标计算