51

そのため、多くの画像が関連付けられたメイン オブジェクトがあります。Image もオブジェクトです。

コレクションビューコントローラーがあり、そのコントローラーにあるとします

cellForItemAtIndexPath

主なオブジェクトに基づいて、現在の画像が関連付けられている場合は、selected を true に設定します。しかし、ユーザーがいつでもその現在のセルを「選択解除」して、メインオブジェクトとの関連付けを削除できるようにしたいと考えています。

「selected to true」を設定すると、主なオブジェクトと画像の間に関係がある場合、cellForItemAtIndexPath選択解除はオプションではなくなります。

didDeselectItemAtIndexPath

didSelectItemAtIndexPath

ログでテストして、それらが呼び出されるかどうかを確認します。セルが選択済みに設定されている場合、ネザーが呼び出されますが、セルを選択済みに設定していない場合は、必要なcellForItemAtIndexPathものをすべて選択および選択解除できます。

これは、コレクション ビューが機能することになっている意図した方法ですか? 私はドキュメントを読みましたが、これについては話していないようです。私はドキュメントを解釈して、テーブル ビュー セルと同じように機能することを意味します。いくつかの明らかな変更を加えて

これは、コントローラーが正しく設定され、適切なデリゲート メソッドを使用していることも示しています。

4

15 に答える 15

91

私は同じ問題を抱えていました。設定cell.selected = YESすると[UICollectionView collectionView:cellForItemAtIndexPath:]、セルをタップしてセルの選択を解除できなくなります。

今のところの解決策:とin の両方 を呼び出します。[UICollectionViewCell setSelected:][UICollectionView selectItemAtIndexPath:animated:scrollPosition:][UICollectionView collectionView:cellForItemAtIndexPath:]

于 2013-07-23T13:48:19.767 に答える
48

選択解除の問題がUICollectionViewあり、collectionView で複数選択を許可していないことがわかりました。だから私がテストしていたとき、私は常に同じセルを試しました。単一選択がオンの場合、すでに選択されているセルを選択解除することはできません。

追加する必要がありました:

myCollectionView.allowsMultipleSelection = YES;
于 2013-12-15T11:25:47.440 に答える
46

setSelectedCell クラスにカスタムメソッドはありますか? そのメソッドで呼び出し[super setSelected:selected]ていますか?

複数選択を使用しているときに、一度選択したセルを選択解除できないという不思議な問題がありました。スーパーメソッドを呼び出すと問題が解決しました。

于 2013-11-03T04:32:41.317 に答える
44

これはちょっと古いですが、swift を使用して同じ問題が発生したため、回答を追加します。使用時:

 collectionView.selectItemAtIndexPath(indexPath, animated: true, scrollPosition: [])

セルはまったく選択されませんでした。しかし、使用する場合:

cell.selected = true

選択されましたが、セルを選択/選択解除できなくなりました。

私の解決策(両方の方法を使用):

cell.selected = true
collectionView.selectItemAtIndexPath(indexPath, animated: true, scrollPosition: .None)

この 2 つのメソッドが呼び出されると、次のようになります。

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell

それは完璧に機能しました!

于 2015-07-13T15:19:45.713 に答える
10

UICollectionViewに比べてなぜこんなに散らかっているのかわかりませんUITableViewController...いくつか分かったことがあります。

複数回呼び出される理由setSelected:は、シーケンス メソッドが呼び出されるためです。このシーケンスは、メソッドのシーケンスと非常によく似ていUITextFieldDelegateます。

実際に「選択する必要がある」と尋ねているため、実際にセルを選択する前にメソッドcollectionView:shouldSelectItemAtIndexPath:が呼び出されますか?collectionView

collectionView:didSelectItemAtIndexPath:実際には、collectionViewがセルを選択した後に呼び出されます。したがって、「選択した」という名前です。

これがあなたのケースで起こっていることです(そして私のケースで、これについて何時間も格闘しなければなりませんでした)。

選択されたセルは、ユーザーが再度タッチして選択を解除します。shouldSelectItemAtIndexPath:セルを選択する必要があるかどうかを確認するために呼び出されます。はcollectionViewセルを選択してからdidSelectItemAtIndexPath呼び出されます。この時点で行うことは、セルのselectedプロパティが に設定された後YESです。そのため、次のようなものは機能しcell.selected = !cell.selectedません。

TL;DR -collectionViewデリゲート メソッドでセルの選択を解除して、と returncollectionView:shouldSelectItemAtIndexPath:を呼び出します。deselectItemAtIndexPath:animated:NO

私がしたことの短い例:

- (BOOL)collectionView:(OPTXListView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *selectedItemIndexPaths = [collectionView indexPathsForSelectedItems];

    if ([selectedItemIndexPaths count]) {
        NSIndexPath *selectedIndexPath = selectedItemIndexPaths[0];

        if ([selectedIndexPath isEqual:indexPath]) {
            [collectionView deselectItemAtIndexPath:indexPath animated:YES];

            return NO;
        } else {
            [collectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];

            return YES;
        }
    } else {
        [collectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];

        return YES;
    }
}
于 2015-04-29T05:40:23.947 に答える
7

これがSwift 2.0に対する私の答えです。

viewDidLoad() で以下を設定できました

collectionView.allowsMultipleSelection = true;

次に、これらのメソッドを実装しました

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    let cell = collectionView.cellForItemAtIndexPath(indexPath) as! MyCell
    cell.toggleSelected()
}

func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
    let cell = collectionView.cellForItemAtIndexPath(indexPath) as! MyCell
    cell.toggleSelected()
}

最後に

class MyCell : UICollectionViewCell {

    ....

    func toggleSelected ()
    {
        if (selected){
            backgroundColor = UIColor.orangeColor()
        }else {
            backgroundColor = UIColor.whiteColor()
        }
    }

}
于 2015-12-08T18:45:49.477 に答える
2
 func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {

    let cell = collectionView.cellForItemAtIndexPath(indexPath)
    if cell?.selected == true{
        cell?.layer.borderWidth = 4.0
         cell?.layer.borderColor = UIColor.greenColor().CGColor
    }   
}func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
    let cell = collectionView.cellForItemAtIndexPath(indexPath)
    if cell?.selected == false{
            cell?.layer.borderColor = UIColor.clearColor().CGColor
    }

}

私が見つけた簡単な解決策

于 2016-02-09T17:12:37.800 に答える
2

私はカスタムセルサブクラスを使用しています。私にとっては、サブクラスに設定self.selected = falseする必要prepareForReuse()がありました。

于 2017-02-14T21:23:52.600 に答える
2

iOS 9 の時代に生きているので、ここでチェックすべきことがいくつかあります。

  1. collectionView.allowsSelectionに設定されているか確認してくださいYES
  2. collectionView.allowsMultipleSelectionに設定されているか確認してくださいYES(その機能が必要な場合)

今度はファン部分です。Apple に耳を傾け、それ自体の代わりに設定backgroundColorした場合、それが表示されないように隠したことになります。なぜなら:cell.contentViewcellselectedBackgroundView

(lldb) po cell.selectedBackgroundView
<UIView: 0x7fd2dae26bb0; frame = (0 0; 64 49.5); autoresize = W+H; layer = <CALayer: 0x7fd2dae26d20>>

(lldb) po cell.contentView
<UIView: 0x7fd2dae22690; frame = (0 0; 64 49.5); gestureRecognizers = <NSArray: 0x7fd2dae26500>; layer = <CALayer: 0x7fd2dae1aca0>>

(lldb) pviews cell
<MyCell: 0x7fd2dae1aa70; baseClass = UICollectionViewCell; frame = (0 0; 64 49.5); clipsToBounds = YES; hidden = YES; opaque = NO; layer = <CALayer: 0x7fd2dae1ac80>>
   | <UIView: 0x7fd2dae26bb0; frame = (0 0; 64 49.5); autoresize = W+H; layer = <CALayer: 0x7fd2dae26d20>>
   | <UIView: 0x7fd2dae22690; frame = (0 0; 64 49.5); gestureRecognizers = <NSArray: 0x7fd2dae26500>; layer = <CALayer: 0x7fd2dae1aca0>>
   |    | <UIView: 0x7fd2dae24a60; frame = (0 0; 64 49.5); clipsToBounds = YES; alpha = 0; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7fd2dae1acc0>>
   |    | <UILabel: 0x7fd2dae24bd0; frame = (0 0; 64 17.5); text = '1'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fd2dae240c0>>
   |    | <UILabel: 0x7fd2dae25030; frame = (0 21.5; 64 24); text = '1,04'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fd2dae25240>>

(lldb) po cell.contentView.backgroundColor
UIDeviceRGBColorSpace 0.4 0.4 0.4 1

cell.selectedしたがって、 selectedBackgroundView (とでオン/オフされるもの) を使用する場合は、次のselectItemAtIndexPath...ようにします。

cell.backgroundColor = SOME_COLOR;
cell.contentView.backgroundColor = [UIColor clearColor];

そしてそれはうまくいくはずです。

于 2016-03-25T11:25:28.930 に答える
1

問題を理解しているかどうかはわかりませんが、選択されたステータスはセルごとに設定され、セル内のすべてのサブビューが含まれます。「主要なオブジェクトには、それに関連付けられた多くの画像があります」という意味を説明していません。サブビューのように関連付けられていますか? または、正確にはどのような協会を意味しますか?

私には設計上の問題のように聞こえます。おそらく、必要な関連オブジェクトを含む UIView サブクラスが必要です。そのサブクラスはコンテンツ ビューとして設定できます。たとえば、画像、説明、および画像に関連する録音がある場合にこれを行います。すべてがサブクラスで定義され、これらのサブクラスのそれぞれが 1 つのセルのコンテンツ ビューになります。

また、関連する画像をそれらを含むフォルダーに配置することも使用しました。この設定では、フォルダーと画像にはそれぞれサブクラスがあり、いずれかがコンテンツ ビューとしてセルに添付される場合があります (これらは単一のエンティティとしてコア データに格納されます)。

おそらく、あなたの問題をさらに説明できますか?

于 2013-03-11T06:44:18.907 に答える
0

コレクションビューの選択、選択解除の問題は、私がこれを行ったときに解決しました。で、次をviewDidLoad追加collViewRiskPreferences.allowsMultipleSelection = falseして追加します

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier:"MyCell", for: indexPath) as? MyCell else { return UICollectionViewCell() }
        
        cell.setupCellStyle(isSelected: false)
        
        return cell
    }

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let cell = collectionView.cellForItem(at: indexPath) else { return }
        cell.setupCellStyle(isSelected: true)
    }
    
    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
        guard let cell = collectionView.cellForItem(at: indexPath) else { return }
        cell.setupCellStyle(isSelected: false)
    }

class MyCell: UICollectionViewCell {
        func setupCellStyle(isSelected: Bool) {
            if(isSelected) {
                self.contentView.backgroundColor = UIColor.blue
            } else {
                self.contentView.backgroundColor = UIColor.green
            }
        }
    }
于 2020-10-14T10:05:59.873 に答える
-1

セルの選択と選択解除は、backgroundView と選択された背景ビューを設定することによって最適に処理されます。これらのビューの両方のフレームが layoutSubviews メソッドで正しく設定されていることを確認することをお勧めします (IB を介して選択ビューと背景ビューを設定する場合)。

正しい背景ビューが透けて見えるように、contentView の背景色 (ある場合) をクリアに設定することを忘れないでください。

セルの選択を直接 (つまり、cell.selected = YES を介して) 設定しないでください。コレクション ビューでこの目的のために設計されたメソッドを使用してください。ドキュメントで明確に説明されていますが、ガイド間で情報が多少断片化されていることに同意します.

collectionView データソースでセルの背景色を直接調べる必要はありません。

また、最後の注意として、[super prepareForReuse] と [super setSelected:selected] をセルのクラスに実装する場合は、セルのスーパークラスがセル選択を実行できないようにすることを忘れないでください。

この件についてさらに説明が必要な場合は、私に連絡してください。

于 2015-11-04T02:45:16.960 に答える