使用委托从按钮传递信息以突出显示单元格

Posted

技术标签:

【中文标题】使用委托从按钮传递信息以突出显示单元格【英文标题】:Using a delegate to pass information from button to highlight cell 【发布时间】:2016-07-15 01:24:01 【问题描述】:

我有一个父视图控制器和一个子视图控制器,我需要将信息从子视图控制器中的按钮传递回父视图控制器,以便突出显示正确的 tableViewCell 文本。

在父视图控制器中,当点击单元格时,单元格文本会突出显示,子视图控制器会在屏幕上弹出并播放选定的歌曲。但是,在子视图控制器上有一个向后跳过和向前跳过按钮,因此当按下其中任何一个并再次显示父视图控制器时,单元格文本现在需要为不同的单元格突出显示而不是突出显示之前

所以我已经为每个视图控制器添加了正确的委托样板代码,但我不确定从子视图控制器获取的最佳信息以发送回父视图控制器,以及如何使用它。

子视图控制器

-(IBAction)indexChanged:(UISegmentedControl *)sender

    NSURL *musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Blip_Select" ofType:@"wav"]];
    AVAudioPlayer *click  = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile  error:nil];

    switch (self.segmentedControl.selectedSegmentIndex)
    
        case 0:
            [click play];
            [click play];
            [musicPlayer skipToPreviousItem];
            break;
        case 1:
            [click play];
            if ([musicPlayer playbackState] == MPMusicPlaybackStatePlaying) 
                [musicPlayer pause];
             else 
                [musicPlayer play];
            
            break;
        case 2:
            [click play];
            [click play];
            [musicPlayer skipToNextItem];
        default:
            break; 
     

我会在上述每个 switch 语句中添加一些内容,但 我不确定哪种方法最有效

因为这是 父视图控制器中的样子:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    AlbumsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    MPMediaItem *rowItemAlbum = [[albumsArrayForTVC objectAtIndex:indexPath.section] representativeItem];
    NSString *albumDetailTitle = [rowItemAlbum valueForProperty:MPMediaItemPropertyAlbumTitle];
    MPMediaQuery *albumMPMediaQuery = [MPMediaQuery albumsQuery];
    MPMediaPropertyPredicate *albumPredicate = [MPMediaPropertyPredicate predicateWithValue: albumDetailTitle forProperty: MPMediaItemPropertyAlbumTitle];
    [albumMPMediaQuery addFilterPredicate:albumPredicate];
    NSArray *albumTracksArray = [albumMPMediaQuery items];

    MPMediaItem *rowItemSong = [[albumTracksArray objectAtIndex:indexPath.row] representativeItem];
    NSString *songTitle = [rowItemSong valueForProperty:MPMediaItemPropertyTitle];
    cell.textLabel.text = songTitle;
    cell.textLabel.highlightedTextColor = [UIColor brownColor];

    return cell;

我知道我会添加某种方法,然后重新加载表格,但我不确定解决这个问题的最佳方法。有任何想法吗?谢谢!

【问题讨论】:

在您的子 VC 上实现委托,然后使用父 VC 上的数据源,然后重新加载表,例如设置一个 Int 来决定突出显示哪一行 尝试在子视图控制器中使用 Block 作为回调。并定义块在父视图控制器中的作用。 @Tj3n 这一切都说得通,也符合我的想法,但不确定如何执行您所说的 Int 部分,例如如何准确地实现+1/-1 在父 VC 中你知道吗? @EricXuan 你在说什么区块? 【参考方案1】:

在您的子视图控制器中创建委托

 @protocol ChildView_Delegate <NSObject>
 -(void)reSelectTableRow:(int)index
 @end

在你的子视图控制器中创建一个属性

@property (nonatomic) id delegate;

当您按下前进和后退按钮时,请执行以下操作。

-(IBAction)forward:(id)sender
   if(_delegate)
      [_delegate reSelectTableRow:position+1];
   

回到你的主控制器中实现 ChildView_Delegate 并像这样实现它的方法

 -(void)reSelectTableRow:(int)index
   if(index<songsArray.count)
     //define a index path
      NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index  inSection:0];
     //select a row of table view programatically
     [tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:
     UITableViewScrollPositionNone];
   
 

【讨论】:

是的,这是有道理的,我认为这需要某种 +1/-1 解决方案,但不确定如何在主控制器上实现该解决方案 (要尝试实现!) 我想我已经知道了,除了现在需要突出显示与以前突出显示不同的单元格的文本,但现在没有突出显示单元格文本? 我也不确定inSection: 应该是0 对吗?还是应该一直是0 section 是关于您要突出显示的部分行【参考方案2】:

    在您的子控制器中定义一个协议。这个协议应该有一个类似 'didSelectSkipButton' 的方法,它接受一些参数来表示按下的按钮的类型。

    为您的子视图控制器定义一个委托属性,符合协议。

    在孩子的 indexChanged 中,向代理发送 didSelectSkipButton 消息,传递代表按下按钮的值。

    在您的父 vc 中,将自己设置为子代理并实现协议方法。在didSelectSkipButton 中,使用indexPathForSelectedRow 查找表视图的当前行,并根据按下的按钮在[indexpath row] 中加或减一。检查新行索引是否在表视图的有效范围内。然后发送您的表格视图 selectRowAtIndexPath:animated:scrollPosition: 消息选择新行。

【讨论】:

感谢您的回复! #3 + #4 是我还没有的东西,我正试图弄清楚如何解决。让我试着用这个来做一个解决方案。 在#4 中,我有“使用 indexPathForSelectedRow 查找表视图的当前行”NSIndexPath *indexPathSelected = [self.tableView indexPathForSelectedRow]; 并检查新行索引是否在表视图的有效范围内。然后向您的表视图发送一条 selectRowAtIndexPath:animated:scrollPosition: 消息以选择新行。”if(indexPath &lt; albumTracksArrayForTVC.count) [self.tableView selectRowAtIndexPath:indexPathSelected animated:YES scrollPosition: UITableViewScrollPositionNone]; 但我错过了“并根据按下的按钮从 [indexpath row] 中添加或减去一个。”在两者之间。你知道我应该在那里做什么吗? 我从孩子那里得到了 -/+ '[_delegate didSelectSkipButton:-1];'用于向后跳,[_delegate didSelectSkipButton:+1]; 用于向前跳。 此外,现在需要为不同的单元格突出显示文本,而不是之前突出显示的单元格,但现在没有单元格文本被突出显示?【参考方案3】:

在父级中添加委托方法

 @protocol childDelegate <NSObject>
 -(void) updateTable
 @end

@property (assign) id <childDelegate> cDelegate;

然后在父级中添加相同的方法

-(void) updateTable

  [yourTableView reloadData];


-(IBAction)indexChanged:(UISegmentedControl *)sender

  [self.cDelegate updateTable];

希望对你有帮助。

【讨论】:

感谢您的回复!我已经拥有所有样板委托代码,但不确定如何实现对父级 +1/-1 的方法,你知道吗?关于如何做到这一点的任何想法? 更重要的是,现在需要为不同的单元格突出显示文本,而不是之前突出显示的,你知道怎么做吗?

以上是关于使用委托从按钮传递信息以突出显示单元格的主要内容,如果未能解决你的问题,请参考以下文章

在哪里突出显示 UICollectionViewCell:委托还是单元格?

C# ListView 详细信息,突出显示单个单元格

点击时突出显示 tableview 单元格,按下警报控制器操作按钮时取消突出显示

回退时 UITableViewController 单元格保持突出显示

突出显示时,表格单元格中的 iOS 自定义按钮变暗

UIButton 在单元格被触摸时也会突出显示