35

コレクション ビュー プログラミング ガイドによると、UICollectionViewDelegate. このような:

- (void)collectionView:(PSUICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    MYCollectionViewCell *cell = (MYCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
    [cell highlight];
}

- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    MYCollectionViewCell *cell = (MYCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
    [cell unhighlight];
}

このアプローチで私が気に入らないのは、デリゲートにセル固有のロジックが追加されることです。実際、プロパティUICollectionViewCellを介して、強調表示された状態を個別に管理しhighlightedます。

それでは、オーバーライドsetHighlighted:はよりクリーンなソリューションではないでしょうか?

- (void)setHighlighted:(BOOL)highlighted
{
    [super setHighlighted:highlighted];
    if (highlighted) {
        [self highlight];
    } else {
        [self unhighlight];
    }
}

デリゲート アプローチの代わりにこのアプローチに欠点はありますか?

4

7 に答える 7

54

highlightedドキュメントにあるように、セルが強調表示されている間に変更されるプロパティに依存できます。たとえば、次のコードは、強調表示されたときにセルを赤くします (ただし、サブビューではありません)。

- (void)setHighlighted:(BOOL)highlighted {
    [super setHighlighted:highlighted];
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    if (self.highlighted) {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetRGBFillColor(context, 1, 0, 0, 1);
        CGContextFillRect(context, self.bounds);
    } 
}

そして、このようなものを追加すると、背景は紫 (赤 + 不透明な青) になります。

- (void)collectionView:(UICollectionView *)colView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [colView cellForItemAtIndexPath:indexPath];
    cell.contentView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.5];
}

- (void)collectionView:(UICollectionView *)colView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [colView cellForItemAtIndexPath:indexPath];
    cell.contentView.backgroundColor = nil;
}

したがって、両方を一緒に使用できます (必ずしも両方がセルの外観を変更するとは限りません)。違いは、デリゲート メソッドにはindexPath. 複数選択を作成したり (このメソッドを選択デリゲート メソッドと一緒に使用します)、セルが強調表示されているときにプレビューを表示したり、他のビューでアニメーションを表示したりするために使用できます...このデリゲートにはかなりの数のアプライアンスがあります。私の意見では方法。

結論として、セルの外観をセル自体で処理するように残し、デリゲート メソッドを使用して、コントローラーが同時にクールなものを作成できるようにします。

于 2013-03-18T18:41:11.480 に答える
17

考えられる 2 つのアプローチを以下に概説します。

セルのサブクラス化

からすでにサブクラス化されている場合は、よりクリーンなアプローチUICollectionViewCell

class CollectionViewCell: UICollectionViewCell {

    override var highlighted: Bool {
        didSet {
            self.contentView.backgroundColor = highlighted ? UIColor(white: 217.0/255.0, alpha: 1.0) : nil
        }
    }
}

UICollectionViewDelegate

クリーン度が低く、コレクション ビュー デリゲートがセルのプレゼンテーション ロジックを認識する必要があります。

func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: NSIndexPath) {

    if let cell = collectionView.cellForItemAtIndexPath(indexPath) {
        cell.contentView.backgroundColor = UIColor(white: 217.0/255.0, alpha: 1.0) // Apple default cell highlight color
    }
}


func collectionView(collectionView: UICollectionView, didUnhighlightItemAtIndexPath indexPath: NSIndexPath) {

    if let cell = collectionView.cellForItemAtIndexPath(indexPath) {
        cell.contentView.backgroundColor = nil
    }
}
于 2016-01-13T22:15:53.547 に答える
7

セルを強調表示するのに十分です(Swift 4)

class MyCollectionViewCell: UICollectionViewCell {
...
    override var isHighlighted: Bool {
        didSet {
            if isHighlighted {
                self.contentView.alpha = 0.6
            }
            else {
                self.contentView.alpha = 1.0
            }
        }
    }
}
于 2018-12-20T10:42:16.203 に答える
2

UICollectionViewCell.h から直接取得したとおり - と の両方setSelectedをオーバーライドしsetHighlightedて正しいです。状況に応じて、選択時に自動的に交換されるカスタム ビューbackgroundViewを割り当てることを検討できます。selectedBackgroundView

// Cells become highlighted when the user touches them.
// The selected state is toggled when the user lifts up from a highlighted cell.
// Override these methods to provide custom UI for a selected or highlighted state.
// The collection view may call the setters inside an animation block.
@property (nonatomic, getter=isSelected) BOOL selected;
@property (nonatomic, getter=isHighlighted) BOOL highlighted;

// The background view is a subview behind all other views.
// If selectedBackgroundView is different than backgroundView, it will be placed above the background view and animated in on selection.
@property (nonatomic, retain) UIView *backgroundView;
@property (nonatomic, retain) UIView *selectedBackgroundView;
于 2014-10-20T18:46:54.427 に答える