Возврат к UIView с данными, уже переданными ему - PullRequest
0 голосов
/ 05 января 2012

Я только начал разрабатывать для iOS.Чтобы перейти прямо к делу ... Я создал UITableViewController, заполненный некоторыми аудиофайлами, которые я хочу воспроизвести.Я успешно передал строку выбранных строк и изменил представления на «Вид воспроизведения», который является UIViewController. Оттуда я воспроизводю звук с помощью avaudioplayer. После возврата к предыдущему экрану со встроенным контроллером навигации и выбора другого аудиоотслеживать, он создает совершенно новый экземпляр avaudioplayer и воспроизводит вновь выбранный аудио поверх старого выбранного аудио без возможности остановить старый.Как я могу создать представление «Now Playing», где я могу загрузить недавно выбранный аудиои очистить старый звук ??

    #import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

@interface NowPlayingViewController : UIViewController{

    AVAudioPlayer *audioPlayer;

    //playPause button images
    UIImage *playImg;
    UIImage *pauseImg;

    IBOutlet UIButton *playPauseButton;

    //Volume slider
    NSTimer *volumeTimer;
    IBOutlet UISlider *volumeSlider;

}

//playPause button action
- (IBAction)playPause:(id)sender;
@end

Вот файл реализации.

 #import "NowPlayingViewController.h"

    @implementation NowPlayingViewController


    #pragma mark - My actions
    //Audio Player Controllers

    //Play the selected audio.
    - (IBAction)playPause:(id)sender
    {
        if (![audioPlayer isPlaying]) {
            [playPauseButton setImage:pauseImg forState:UIControlStateNormal];
            [audioPlayer play];
        } else { 
            [playPauseButton setImage:playImg forState:UIControlStateNormal];
            [audioPlayer pause];
        }
    }

    -(void)updateVolumeSlider
    {
        [audioPlayer setVolume:volumeSlider.value];
    }

    #pragma mark - Initialization
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }

    - (void)didReceiveMemoryWarning
    {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];

        // Release any cached data, images, etc that aren't in use.
    }

    #pragma mark - View lifecycle
    - (void)viewDidLoad
    {
        [super viewDidLoad];

        //Instantiate needed variables
        playImg = [UIImage imageNamed:@"Play.png"];
        pauseImg = [UIImage imageNamed:@"Pause.png"];

        //Prepare the audio player
        NSString *path = [[NSBundle mainBundle] pathForResource:self.title ofType:@"m4a"];
        audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
        [audioPlayer prepareToPlay];

        //Setup the volume slider
        volumeTimer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(updateVolumeSlider) userInfo:nil repeats:YES];
    }

Заголовок MainView

#import <UIKit/UIKit.h>

@interface MainTableViewController : UITableViewController{

    NSMutableArray *performanceArray;
    NSMutableArray *recoveryArray;

}

@end

Файл реализации MainView

#import "MainTableViewController.h"
#import "NowPlayingViewController.h"


@implementation MainTableViewController


#pragma mark - Table view
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 2;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
    if(section == 0)
        return @"Performance";
    else
        return @"Recovery";
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if(section == 0)
        return [performanceArray count];
    else
        return [recoveryArray count];
}

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    if(indexPath.section == 0)
        cell.textLabel.text = [performanceArray objectAtIndex:indexPath.row];
    else
        cell.textLabel.text = [recoveryArray objectAtIndex:indexPath.row];
    return cell;
}

#pragma mark - Prepare data to pass
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"Audio Selection Segue"])
    {
        // Get reference to the destination view controller
        NowPlayingViewController *np = [segue destinationViewController];

        //Pass the selected audio title to the Now Playing View
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.tableView.indexPathForSelectedRow];
        np.title = cell.textLabel.text;
    }
}

#pragma mark - didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"Audio Selection Segue" sender:self];
}

#pragma mark - Initialization
- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle
- (void)viewDidLoad
{
    [super viewDidLoad];

    //Instantiate performanceArray
    performanceArray = [[NSMutableArray alloc]initWithObjects:@"Centering", nil];

    //Instantiate recoveryArray
    recoveryArray = [[NSMutableArray alloc]initWithObjects:@"Power Nap", nil];
}

1 Ответ

0 голосов
/ 05 января 2012

Первая часть проста.Вместо того, чтобы создавать новый NowPlayingViewController каждый раз, когда вы хотите перенести его в стек навигации, просто повторно используйте существующий.Затем вам нужно будет передать звуковую ссылку через свойство в NowPlayingViewController.

@interface MyTableViewController {
     NowPlayingViewController *nowPlayingViewController;
}

@implementation MyTableViewController{
     ...
     nowPlayingViewController = [[nowPlayingViewController alloc]init];
     ...
     [nowPlayingViewController setAudio:@"urlToAudio"]
     this.navigationController.pushViewController(nowPlayingViewController);
     ...
}

Редактировать: вышеупомянутое было уместно, только если вы создавали экземпляр viewController, как это и предполагалось.Оказывается, вы использовали раскадровку, которая автоматически создает новые экземпляры viewsControllers в сегментах.Поэтому проблема в том, что вы не останавливаете музыку (см. Ниже).


Что касается 2-й части (музыка не останавливается), вы, кажется, нигде не останавливаете музыку.Сделайте это в вызове делегата «viewDidUnload» или «viewWillDisappear», который вызывается, когда представление больше не используется.


Новое редактирование на основе новых требований:

  • вы хотите, чтобы представление Now Playing управляло музыкой.
  • вы не хотите, чтобы музыка останавливалась, даже если представление Now Playing выгружено.

В этом случаеВы должны отделить AudioPlayer от представления Now Playing.

Вы должны передавать AudioPlayer извне, каждый раз, когда создается представление NowPlaying.Оптимально, чтобы у вас был класс, который поддерживает состояние приложения музыкального проигрывателя.

@interface MusicPlayer : NSObject{        
}

// example
-(bool) isPlaying;
-(bool) isPaused;

-(void) play;
-(void) pause;
-(void) stop;
-(void) changeTrack;

-(NSString *)currentTrack;
//etc.
@end

Затем, когда вы делаете переход, вместо того, чтобы просто сообщать представлению NowPlaying, какую дорожку воспроизводить, передайте ее MusicPlayer.вместо этого.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"Audio Selection Segue"])
    {
        // Get reference to the destination view controller
        NowPlayingViewController *np = [segue destinationViewController];

        //Pass the selected audio title to the Now Playing View
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.tableView.indexPathForSelectedRow];

        [self.player stop];
        [self.player changeTrack:@"urlToTrack"];
        [self.player play];

        np.player = self.player;
    }
}

Теперь вместо кнопок, управляющих тем, что воспроизводить и т. д., пусть ваши кнопки просто отправляют сообщения на ваш музыкальный проигрыватель.С помощью NSNotification вы даже можете позволить музыкальному проигрывателю отправлять события на ваши представления для обновления таких вещей, как название альбома, название дорожки, обложка альбома и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...