自动在UIScrollView中布局图像

时间:2011-06-27 02:50:57

标签: iphone xcode image uiscrollview

我有一个从xml中检索到的图像列表,我希望按顺序将它们填充到uiscrollview,使其看起来像这样。

1 2 3

4 5 6

7 8 9

10

如果只有10张图片,它就会停在这里。

现在我的当前代码就是这个

for (int i = 3; i<[appDelegate.ZensaiALLitems count]-1; i++) {
        UIButton *zenbutton2 =[UIButton buttonWithType:UIButtonTypeCustom];
        Items *ZensaiPLUitems = [appDelegate.ZensaiALLitems objectAtIndex:i];
        NSURL *ZensaiimageSmallURL = [NSURL URLWithString:ZensaiPLUitems.ZensaiimageSmallURL];
        NSLog(@"FVGFVEFV :%@", ZensaiPLUitems.ZensaiimageSmallURL);
        NSData *simageData = [NSData dataWithContentsOfURL:ZensaiimageSmallURL];
        UIImage *itemSmallimage = [UIImage imageWithData:simageData];
        [zenbutton2 setImage:itemSmallimage forState:UIControlStateNormal];
        zenbutton2.frame=CGRectMake( (i*110+i*110)-660 , 300, 200, 250);
        [zenbutton2 addTarget:self action:@selector(ShowNextZensaiPage) forControlEvents:UIControlEventTouchUpInside];
        [scrollView addSubview:zenbutton2];
}

注意CGRectMake,我必须手动分配固定值来定位它们。 有没有办法填充它们而无需手动分配。 例如,一旦第一行有3张图像,图像将自动向下移动一个位置,然后用于其余图像。

2 个答案:

答案 0 :(得分:3)

如果我理解你在说什么,你应该能够编写一个简单的代码块,根据图像编号指定一个位置。

像这样(我是图像编号,从0开始):

- (CGPoint)getImageOrigin:(NSInteger)imageNumber {

    CGFloat leftInset = 30;
    CGFloat xOffsetBetweenOrigins = 80;
    CGFloat topInset = 20;
    CGFloat yOffsetBetweenOrigins = 80;

    int numPerRow = 3;

    CGFloat x = leftInset + (xOffsetBetweenOrigins * (imageNumber % numPerRow));
    CGFloat y = topInset + (yOffsetBetweenOrigins * floorf(imageNumber / numPerRow));

    CGPoint imageOrigin = CGPointMake(x, y);

    return imageOrigin;

}

此处计算的原点是每张图像的左上角。

要计算x值,我从屏幕左侧的最小距离(leftInset)开始。然后,我将从一个图像左侧到下一个图像的距离乘以列(imageNumber % numPerRow)。

Y以类似的方式计算,但为了计算行,我使用imageNumber / numPerRow向下舍入。

编辑:

你让我进一步解释,所以我会看到我能做些什么。

好的,所以我希望能够将图像编号(从0开始)输入到我的函数中,然后我想要原点(左上角点)。

leftInset是视图左边缘与第一张图片左边缘之间的距离。

xOffsetBetweenOrigins是从一个图像的左边缘到同一行的下一个图像的左边缘的距离。因此,如果我将其设置为80并且我的图像宽度为50px,则同一行中的两个图像之间将存在30px的间隙。

topInset就像留下了一样。它是从顶视图的顶边到顶行图像顶边的距离。

yOffsetBetweenOrigins是从图像上边缘到下方图像上边缘的距离。如果我将其设置为80,并且我的图像高度为50px,那么行之间将存在30px的垂直间隙。

numPerRow很简单。它只是每行的图像数量。

要计算图像左上角的x值,我总是从leftInset开始,因为它是常量。如果我在一行的第一个图像上,那将是整个x值。如果我在行的第二个图像上,我需要添加xOffsetBetweenOrigins一次,如果我在第三个,我需要添加两次。

为此,我使用模数(%)运算符。它给了我除法运算的余数,所以当我说imageNumber%numPerRow时,我要求imageNumber / numPerRow的剩余部分。 如果我在第一张图像上(imageNumber = 0),那么3次没有进入0,余数为0.如果我在第二张图像上(imageNumber = 1),那么我有1/3。 3进入1 0次,但​​余数为1,所以我得到xOffsetBetweenOrigins * 1.

对于y值,我做了类似的事情,但不是取模数,而是简单地将imageNumber / numPerRow除以并向下舍入。这样做,我将得到0表示0,1和2.我将得到3表示3,4和5。

编辑:

我突然想到你可能真的一直在问如何使用这种方法。在你的代码中,你会说类似

CGRect newFrame = zenbutton2.frame;
newFrame.origin = [self getImageOrigin:i];
zenbutton2.frame = newFrame;

另一个编辑:

也许你可以试试这个?

CGPoint origin = [self getImageOrigin:i];
zenbutton2.frame = CGRectMake(origin.x, origin.y, width, height);

如果不起作用,请投入

NSLog("Origin Values: %f,%f", origin.x, origin.y);

确保您确实从getImageOrigin获得了回复。

答案 1 :(得分:0)

我想你可能想把你的循环包装在另一个循环中,以获得我称之为2D循环的东西:

for (int row = 0; row < num_rows; row++) {
   for (int col = 0; col < num_cols; col++) {
        // code before
        zenButton2.frame = CGRectMake(origin x dependent on col,
                                      origin y dependent on row,
                                      width,
                                      height);
        // code after
   }
}

x的{​​{1}}和y是图像宽度和高度的倍数,分别是行和列的倍数。希望这是有道理的。