1

whtsアプリのようなフォトスライダーが欲しいです。ビルド フォト ライブラリのすべての写真または一部の写真にアクセスする必要があり、スクロール ビューを使用してスクロールできる必要があります。

別のフォト ビューアーを試してみましたが、すべてにメモリの問題があります。そのため、誰かがそれが機能するソリューションを持っているかどうかはわかりません。本当にありがとうございました。

ありがとうございました、

アンキタ

4

2 に答える 2

1

これはほぼ問題なく動作していますが、バックボード方向のスクロールに小さな問題が 1 つあります。これを試してみてください。進むべき方向を見つけることができ、それを使用してより良い解決策を見つけることができるかもしれません。

(ELCImagePicker を使用して最初にすべての画像を表示し、次に 1 つを選択するとスクロールビューが表示され、一度に 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 ファイルのインターフェイス部分で宣言されているすべての使用済みプロパティとプライベート ivar は、

プライベート・アイバーズ

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 を使用して、高解像度の画像または大量の写真セットでのページング、パン、およびズームのパフォーマンスを向上させることができます。

上でコメントしたように、再利用可能なビュー アプローチを使用すると、一度に 3 つの imagview またはビューのみがメモリに格納されます。写真番号:2 を表示しているとします。そのため、写真:1、2、3 をメモリに保持する必要があります (ちらつきを避けるため)。一度にすべての写真を読み込む必要はありません。写真番号:3 までスクロールすると、ロジックは写真番号:1 を破棄し、写真番号:2,3,4 をロードする必要があります。それでも取得できない場合や、プログラムでこれを行う方法がわからない場合でも、心配する必要はありません。Apple の優れたサンプル コードが利用可能で、必要なすべてのことを実行できます。

サンプルコード

上記のサンプル コードでは、2 つの方法で画像を表示しています。
1つは、画像を画像ビューに直接表示/設定することです。
2番目は、このメソッドを使用してTileViewで画像を描画することです:
- (void)displayTiledImageNamed:(NSString *)imageName size:(CGSize)imageSize

メモリについて多くのことを考えている場合は、間違いなく 2 番目のアプローチを使用する必要があります。

于 2012-08-01T13:22:35.373 に答える