1

我想要像 whts 应用程序那样的照片滑块。它应该访问构建照片库中的所有图片或一些图片,并且应该可以使用滚动视图滚动。

我尝试过使用不同的照片查看器,但一切都有内存问题。所以不确定是否有人有它的工作解决方案。非常感谢您的帮助。

谢谢,

安基塔

4

2 回答 2

1

这几乎可以正常工作,但是后退方向滚动存在一个小问题。试试这个,你可能会找到一些方向,并且可能会找到更好的解决方案。

(已使用 ELCImagePicker 第一次显示所有图像,然后在选择一个呈现时滚动视图以一次显示大图像 10 个图像显示还调整了 ELCImagePickerController 的委托方法以获取所选图像的索引)

首次加载,即从 ELCImagePickerController 中选择图像时

- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info selectedIndex:(NSInteger)_index {
    [self dismissModalViewControllerAnimated:NO];

    for (UIView *v in [scrollview subviews]) {
        [v removeFromSuperview];
    }
    infoItems = [[NSArray alloc]initWithArray:info];
    CGRect workingFrame = scrollview.frame;
    workingFrame.origin.x = 0;
    int indexFrame = picker.selectedIndex;
    newIndex = indexFrame;
    for(int i = 0; i < [info count]; i++) 
    {
        NSDictionary *dict = [info objectAtIndex:i];
        UIImageView *imageview = [[UIImageView alloc] initWithImage:[dict objectForKey:UIImagePickerControllerOriginalImage]];
        [imageview setContentMode:UIViewContentModeScaleAspectFit];
        imageview.frame = workingFrame;
        imageview.tag = i;
        if(i >= indexFrame && i <= indexFrame + 9)
        {
            [scrollview addSubview:imageview];
            workingFrame.origin.x = workingFrame.origin.x + workingFrame.size.width;
        }
    }
    [scrollview setPagingEnabled:YES];
    [scrollview setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height)];
    [scrollview scrollRectToVisible:CGRectMake(0, 0, workingFrame.size.width, workingFrame.size.height) animated:NO];
    self.scrollview.hidden = NO;
    self.pageControll.hidden = NO;
    self.pageControll.numberOfPages = [[scrollview subviews]count];
    index = 0;
    lastContentOffset = scrollview.contentOffset.x;
    NSLog(@"lastContentOffset %.2f",lastContentOffset);
}

之后在 scrollViews 委托方法上

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    NSLog(@"ScrollViewDidEndDecelerating is called with subview(s) %d",[[scrollview subviews]count]); 
    if(lastContentOffset < scrollView.contentOffset.x)
    {

        index += (int)(scrollview.contentOffset.x - lastContentOffset)/scrollview.frame.size.width;
        newIndex += (int)(scrollview.contentOffset.x - lastContentOffset)/scrollview.frame.size.width;
        self.pageControll.currentPage = index;
        NSLog(@"Index incremented %d \n newIndex %d",index,newIndex);
        if(index == [[scrollView subviews]count]-1)
        {
            if(newIndex < [infoItems count]-1)
            {
                [self performSelector:@selector(reloadScrollViewWithNewImages)];
            }
        }
        [Appirater userDidSignificantEvent:YES];
    }
    else if(lastContentOffset > scrollView.contentOffset.x)
    {
        index -= (int)(lastContentOffset - scrollview.contentOffset.x)/scrollview.frame.size.width;
        newIndex -= (int)(int)(lastContentOffset - scrollview.contentOffset.x)/scrollview.frame.size.width;
        self.pageControll.currentPage = index;
        NSLog(@"Index decremented %d \n newIndex %d",index,newIndex);
        if(index == 0)
        {
            if(newIndex > 0)
            {
                newIndex -= 9;
                if(newIndex < 0)
                    newIndex = 0;
                [self performSelector:@selector(reloadScrollViewWithNewImages)];
            }
        }
        [Appirater userDidSignificantEvent:YES];
    }
    lastContentOffset = scrollView.contentOffset.x;
    NSLog(@"New lastContentOffset %.2f",lastContentOffset);
}

并且用于重新加载scrollView的方法如下

-(void)reloadScrollViewWithNewImages
{
    for (UIView *v in [scrollview subviews]) {
        [v removeFromSuperview];
    }
    CGRect workingFrame = scrollview.frame;
    workingFrame.origin.x = 0;
    NSLog(@"reloadScrollView newIndex %d",newIndex);
    int indexFrame = newIndex;
    for(int i = 0; i < [infoItems count]; i++) 
    {
        NSDictionary *dict = [infoItems objectAtIndex:i];
        UIImageView *imageview = [[UIImageView alloc] initWithImage:[dict objectForKey:UIImagePickerControllerOriginalImage]];
        [imageview setContentMode:UIViewContentModeScaleAspectFit];
        imageview.frame = workingFrame;
        imageview.tag = i;
        if(i >= indexFrame && i <= indexFrame + 9)
        {
            [scrollview addSubview:imageview];
            workingFrame.origin.x = workingFrame.origin.x + workingFrame.size.width;
        }
    }
    [scrollview setPagingEnabled:YES];
    [scrollview setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height)];
    [scrollview scrollRectToVisible:CGRectMake(0, 0, workingFrame.size.width, workingFrame.size.height) animated:NO];
    self.scrollview.hidden = NO;
    self.pageControll.hidden = NO;
    index = 0;
    self.pageControll.numberOfPages = [[scrollview subviews]count];
    NSLog(@"number %d",[[scrollview subviews]count]);
    lastContentOffset = scrollview.contentOffset.x;
    NSLog(@"reloadScrollView's lastContentOffset %.2f",lastContentOffset);
}

并且此代码所需的 .h 文件的接口部分中声明的所有使用的属性和私有 ivars 都是

私人 ivars

NSInteger index;
float lastContentOffset;

特性

@property (nonatomic,strong) IBOutlet UIScrollView *scrollview;
@property (strong, nonatomic) NSArray *infoItems;
@property (assign, atomic) int newIndex;

快乐编码:)

于 2012-08-03T07:19:57.540 回答
0

您可以使用 CATiledLayer 来绘制图像。CATiledLayer 可用于提高高分辨率图像或大型照片集的分页、平移和缩放性能。

正如我在上面评论的那样,您可以通过可重用视图方法进行操作,这意味着一次只有三个 imagview 或视图会在内存中。假设您正在显示照片编号:2 因此,您应该将照片:1,2 和 3 保存在内存中(即避免闪烁),无需一次加载所有照片。假设您正在滚动到照片编号:3,那么您的逻辑应该丢弃照片编号:1 并加载照片编号:2、3、4。如果您仍然没有得到或不知道如何以编程方式执行此操作,请不要担心。Apple 的优秀示例代码可以满足您的所有需求。

示例代码

在上面的示例代码中,他们显示了两种显示图像的方式。
一种是直接将图像显示/设置为图像视图。
其次是使用此方法使用 TileView 绘制图像:
- (void)displayTiledImageNamed:(NSString *)imageName size:(CGSize)imageSize

如果您正在考虑很多关于内存的问题,那么您肯定必须使用第二种方法。

于 2012-08-01T13:22:35.373 回答