8

バックグラウンド

UICollectionViewタイルのページ化された水平スクロール ビューを実現するために (初めて) を実装しています。各タイルをフレームの中央に表示し、その姉妹タイルが左右に部分的に表示されるようにしたいと思います (Safari アプリのページ セレクターのようなもの)。組み込みのセルのデキューを利用するために を使用することに興味がUICollectionViewあり、回転した を使用したくありませんUITableView

問題

私が見つけている問題は、 and を使用するpagingEnabled = YESclipsToBounds = NO、ページングが完了するとすぐに、フレームUICollectionViewの外側のセル(配列にない) が削除されることです。この基本的なセットアップを維持しながら、姉妹タイルのプレビューを表示する効果を達成する方法について、誰かアドバイスを提供できますか? それとも、これに間違ってアプローチしていますか?collectionViewvisibleCells

スクリーンショット

始める スクロール 開始スクロール 終了 終わり

スクロール画面は正確です。しかし、最初と最後のショットでは、青の余白に緑が見えるようにしたいと考えています。

これが私のAppDelegate.mの内容です(ここでの基本的なセットアップについてはtutsplus.comのクレジットです):

#import "AppDelegate.h"

@interface ViewController : UICollectionViewController
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"ID"];
    [self.view setBackgroundColor:[UIColor blueColor]];
    // pad the collection view by 20 px
    UIEdgeInsets padding = UIEdgeInsetsMake(20.0, 20.0, 20.0, 20.0);
    [self.collectionView setFrame:UIEdgeInsetsInsetRect(self.view.frame, padding)];
    // set pagingEnabled and clipsToBounds off
    [self.collectionView setPagingEnabled:YES];
    [self.collectionView setClipsToBounds:NO];
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 5;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ID" forIndexPath:indexPath];
    UILabel *label = [[UILabel alloc] initWithFrame:cell.bounds];
    label.textAlignment = NSTextAlignmentCenter;
    label.text = [NSString stringWithFormat:@"%d", indexPath.row];
    [label setBackgroundColor:[UIColor greenColor]];
    [cell.contentView addSubview:label];
    return cell;
}
@end

@implementation AppDelegate
{
    ViewController *vc;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // setup the UICollectionViewFlowLayout
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    layout.itemSize = CGSizeMake(280, 280);
    layout.minimumInteritemSpacing = 0;
    layout.minimumLineSpacing = 0;
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    // add a custom UICollectionViewController to the window
    vc = [[ViewController alloc] initWithCollectionViewLayout:layout];
    self.window.rootViewController = vc;
    self.window.backgroundColor = [UIColor yellowColor];
    [self.window makeKeyAndVisible];
    return YES;
}
@end
4

4 に答える 4

10

これに対する解決策は、実際には非常に単純であることがわかりました。UICollectionViewCellページスクロールが終了した後、コレクションビューのフレーム内にセルを表示するのに十分なピクセルだけセルをオーバーラップする必要がありました。関連するコードは

layout.itemSize = CGSizeMake(300, 300);
layout.minimumLineSpacing = -20.0;

そして、 をサブクラス化しUICollectionViewFlowLayout、メソッドをオーバーライドして(CGSize)collectionViewContentSize、セルの重複していないサイズを返しました。

于 2013-01-24T16:12:12.703 に答える
0

私はcollectionViewの専門家ではありませんが、cellForItemAtIndexPathの次の行で実行できる可能性があります。

[cell.contentView addSubview:label];

呼び出されるたびに、別のラベルサブビューがセルに追加されます。既存のラベルまたはサブクラスUICollectionViewCellを確認しますか?

于 2013-01-23T17:33:50.730 に答える
0

-pointInside:withEvent:コレクション ビューのフレームの外でスクロール ジェスチャを開始できるようにオーバーライドすることもできます。UIEdgeInsetsコレクション ビュー サブクラスのプロパティを使用してこれを行います。

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGRect extendedBounds = UIEdgeInsetsInsetRect(self.bounds, self.touchAreaInsets);

    return CGRectContainsPoint(extendedBounds, point);
}

App Store の安全性が必要ない場合は、オーバーライド_visibleBoundsして負の間隔のハックを回避できます。

- (CGRect)_visibleBounds {
     return UIEdgeInsetsInsetRect(self.bounds, self.touchAreaInsets);
}

コードサイズにあまりこだわらず、App Store の安全性が必要な場合は、 PSTCollectionViewvisibleBoundRectsをサブクラス化し、同じ効果のためにオーバーライドすることもできます。

于 2014-07-22T20:20:16.893 に答える