2017-09-29 3 views
0

テーブルビュー内の上位3つのセルには、「リス」という単語が含まれています。私のテーブルの複数のセルでUILabelが 'リス'と言う場合、3つのセルの最初のセルのみを表示するようにする方法はありますか?Obj-C:処理中のセルに同じUILabel値が含まれている場合にのみ、1セル(最上位セル)を返しますか?

E.g. if UILabel userName in tableviewCell is equal to @"Squirrels", only show one table view cell in the table that contains Squirrels in the UILabel

これは意味があります。前もって感謝します!


EDIT:私は成功し、複数の共通の「名前」の値を含む最初の配列を取得しました(以下のコード、編集を参照してください)。私が試してみて、私は、次のクラッシュエラーを取得する私のテーブルビューに、これらの値(firstFoundObject)を表示する場合それは、言った:

-[__NSDictionaryI objectAtIndex:]: unrecognized selector sent to instance 0x1c01a5a20 2017-10-03 23:01:51.728128-0700 pawswap[623:85420] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI objectAtIndex:]: unrecognized selector sent to instance 0x1c01a5a20'

ViewController.m

- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 

    NSString *nodeTitle = self.messages[0][@"name"]; 

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", nodeTitle]; 
    NSArray *filteredArray = [self.messages filteredArrayUsingPredicate:predicate]; 
    id firstFoundObject = nil; 
    firstFoundObject = filteredArray.count > 0 ? filteredArray.firstObject : nil; 

    NSMutableArray *firstObjects = firstFoundObject; 

    return [firstObjects count]; 


} 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    NSString *nodeTitle = self.messages[0][@"name"]; 

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", nodeTitle]; 
    NSArray *filteredArray = [self.messages filteredArrayUsingPredicate:predicate]; 
    id firstFoundObject = nil; 
    firstFoundObject = filteredArray.count > 0 ? filteredArray.firstObject : nil; 

    NSMutableArray *firstObjects = firstFoundObject; 

    static NSString *PointsTableIdentifier = @"MyMessagesCell"; 

    MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier]; 
    if (cell == nil) 
    { 
     NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyMessagesCell" owner:self options:nil]; 
     cell = [nib objectAtIndex:0]; 


    } 




    NSDictionary *receivedSubjectLine = [firstObjects objectAtIndex:indexPath.row]; 

    NSString *messageSubject = [receivedSubjectLine objectForKey:@"node_title"]; 


    [cell.subjectLine setText:messageSubject]; 



    NSDictionary *fromUser = [firstObjects objectAtIndex:indexPath.row]; 

    NSString *userName = [fromUser objectForKey:@"name"]; 

    [cell.senderName setText:userName]; 




    NSDictionary *receivedBody = [firstObjects objectAtIndex:indexPath.row]; 

    NSString *messageBody = [receivedBody objectForKey:@"body"]; 

    [cell.fullMessage setText:messageBody]; 




    NSDictionary *messageReceived = [firstObjects objectAtIndex:indexPath.row]; 

    NSString *timeReceived = [messageReceived objectForKey:@"published at"]; 

    NSLog(@"Message Received at %@", timeReceived); 

    [cell.receivedStamp setText:timeReceived]; 




    return cell; 

} 

PREVIOUS

ViewController.m

#pragma mark - Table view data source 

- (int)numberOfSectionsInTableView: (UITableView *)tableview 
{ 
    return 1; 
} 

- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return [self.messages count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *PointsTableIdentifier = @"MyMessagesCell"; 

    MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier]; 
    if (cell == nil) 
    { 
     NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyMessagesCell" owner:self options:nil]; 
     cell = [nib objectAtIndex:0]; 
    } 

    NSDictionary *receivedSubjectLine = [self.messages objectAtIndex:indexPath.row]; 
    NSString *messageSubject = [receivedSubjectLine objectForKey:@"node_title"]; 
    [cell.subjectLine setText:messageSubject]; 

    NSDictionary *fromUser = [self.messages objectAtIndex:indexPath.row]; 
    NSString *userName = [fromUser objectForKey:@"name"]; 
    [cell.senderName setText:userName]; 

    NSDictionary *receivedBody = [self.messages objectAtIndex:indexPath.row]; 
    NSString *messageBody = [receivedBody objectForKey:@"body"]; 
    [cell.fullMessage setText:messageBody]; 

    NSDictionary *messageReceived = [self.messages objectAtIndex:indexPath.row]; 
    NSString *timeReceived = [messageReceived objectForKey:@"published at"]; 
    [cell.receivedStamp setText:timeReceived]; 

    return cell; 
} 
+0

私はあなたの質問を完全に理解していませんが、テーブルビューのセル数を変更したい場合は、あなたのデータソースに変更を加える必要があると思います。 – 3stud1ant3

+0

私が考えるベストソリューションは、 'self.messages'の一意の要素を含む二次配列を作成し、この配列で動作させます。配列から重複を削除するには、https://stackoverflow.com/a/19373981/3824335を参照してください。 – user2319066

+0

私はあなたが多くの質問をクリアしていないと思います。特に「UILabelのリスを含む表の表ビューセルを1つだけ表示しますか?」 – manismku

答えて

1

基本的には、firstObjectがDictionary型で、NSMutableArrayに型キャストしていることが原因です。以下の行を確認してください:

id firstFoundObject = nil; firstFoundObject = filteredArray.count > 0 ? filteredArray.firstObject : nil;

フィルタリングされていることがわかりましたら、配列をご覧ください。あなたはfirstFoundObjectに取り込むアプリケーション内の辞書としてfirstObjectが、後であなたはそれがここで入力しNSMutableArrayの作っている:

NSMutableArray *firstObjects = firstFoundObject;

以降、あなたがここに取得しようとすると、それは

NSDictionary *receivedSubjectLine = [firstObjects objectAtIndex:indexPath.row];

正しいクラッシュ - 基本を - コードのバージョンは次のようになります

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

static NSString *PointsTableIdentifier = @"MyMessagesCell"; 
MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier]; 
if (cell == nil) 
{ 
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyMessagesCell" owner:self options:nil]; 
    cell = [nib objectAtIndex:0]; 
} 

[cell.subjectLine setText:[self.recvMessage objectForKey:@"node_title"]]; 
[cell.senderName setText:[self.recvMessage objectForKey:@"name"]]; 
[cell.fullMessage setText:[self.recvMessage objectForKey:@"body"]]; 
[cell.receivedStamp setText:[self.recvMessage objectForKey:@"published at"]]; 

return cell;   
} 

最適化されていませんが、それでもあなたのために働くことができます。

COUNTの問題:あなたが呼び出すときに[firstObjectsカウント]あなたが辞書としてfirstFoundObjectを持っているので、あなたがnumberOfRowsInSectionの内側に持っている上に、あなたのコードで

NSMutableDictionary *firstObjects = firstFoundObject;
return [firstObjects count];

有効なコールであり、それは返します辞書内のキーの数。

あなたは好きなように変更します:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; 
{ 

    NSInteger rowCount = filteredArray.count; 
self.recvMessage = rowCount? filteredArray.firstObject: nil; 
return rowCount? 1: 0; 

} 

、あなたが実際にフィルタオブジェクトを格納し、新たなデータを持っています。

@property (nonatomic) NSDictionary *recvMessage; 

希望します。

+0

これはクラッシュしません(どっちです!)、何らかの理由でそれがフィルタリングされて(YAY)、11回目と同じ最初の項目が表示されますか?ははは。 – Brittany

+0

私はあなたが上で作った編集をしました、そして、それはまだ同じものの11を返します。私のfilteredArrayにはname == nodeTitleのための11種類の異なる*結果が含まれていますが、その理由を想定しています。上記は、私のテーブルビューの最初の結果を11回表示しています...私は単にそれが私のフィルタリングされたアイテムの最初の結果を表示したいと思っています笑 – Brittany

+0

それは奇妙です。しかし、すべての方法を変更しました。今はうまくいくはずです。 – manismku

1

はいあなたはあなたが前にそれを行う例えばのtableView、 を実行します 、それを容易に行うことができます

- (void)viewDidLoad 
{ 

[super viewDidLoad]; 


    NSMutableDictionary* NameDictionary=[[NSMutableDictionary alloc] init]; 

    NSString* PreviousName; 

    int oneTime=0; 

    for(int i=0;i<[self.messages count];i++){ 

     NSDictionary *fromUser = [self.messages objectAtIndex: i]; 

     NSString *userName = [fromUser objectForKey:@"name"]; 

     if(oneTime==0) 
     { 

      PreviousName=userName; 

      [NameDictionary addObject:[self.messages objectAtIndex: i]]; 

      oneTime=1; 
     } 

     if(oneTime!=0) 
     { 

      if([PreviousName isEqualToString: userName]) 
      { 

      } 

      else{ 

       [NameDictionary addObject:[self.messages objectAtIndex: i]]; 

      } 

      PreviousName=userName; 
     } 
    } 
} 
+0

self.messagesはNSMutableArrayです(NSMutableDictionaryを変更したので、上記のコードではエラーは発生しません)。つまり、上記のviewDidLoadの中に配置し、何も起こっていないようだ?私もif文をログに記録し、トリガーされたように見えません。しかし、上記のコードをNumberOfRowsInSectionに貼り付けると、コードはトリガされますが、フィルタリングは行われません。 – Brittany

+0

親切に私のメールであなたのプロジェクトを送ってください、私のプロフィールでメールしてください。私はあなたの必要に応じてそれを修正しようとします。 –

0

あなたが@「リス」に等しいSENDERNAME性質を持つ細胞を除外するために頼む、あなたはあなたのデータソースが設定された後に変更することを効果的に求めています。これにより、numberOfRowsInSectionメソッドに問題が発生します。このメソッドは、データソースが設定された後でフィルタリングが行われる場合に必要な数より多くの行を返します。

答えのコメントの1つとして、「self.messagesのユニークな要素を含み、この配列で動作するセカンダリアレイを作成する」ことが示唆されています。テーブルビューのデータソースを構成する配列は、フィルタリングを必要としません。テーブルビューはそれを提示できるだけでなければなりません。

私は上記の答えにコメントする十分な評判を持っていれば、self.messagesが変わらないので正しく動作しないと言うでしょう。 NameDictionaryで「重複しない」オブジェクトを収集する代わりに、NSMutableArrayでそれらを収集することを検討してください。この新しいフィルタリングされた配列は、配列のデータソースである必要があります。この配列をこのViewControllerの外でフィルタリングして、配列がこのビューコントローラに到着したらself.messagesに割り当てることができます。

ちょうど隣同士に見える重複は、このanswerを考慮することとは対照的に、すべての重複を排除するために探している場合。

関連する問題