Matt Gallagher的AudioStream:如何处理视图控制器弹出

嗯,这是我的第一篇文章 - 在这个网站,个人博客和iPhoneDevSDK论坛之间,我一直能够自己解决问题。我已经为iOS开发了大约五个月,并且从未在Google之外寻求过帮助。但是这一次,我被困住了。 我已经成功实现了Matt Galagher的AudioStream类(必须删除链接,因为SO假定我的帖子是垃圾邮件)到我的应用程序中,我很高兴地报告它工作得很漂亮。我在一个视图控制器中使用它,它实际上是TabBar应用程序中父视图的子视图。事实上,我的实现与Matt的例子没有太大的不同 - 我只改变了一些UI元素。 到目前为止,当用户切换到另一个标签时,我一直在使用
viewDidDisappear
来停止拖缆。但最近我决定,只要应用程序正在运行,就可以让音频流播放,无论顶视图是什么。这是一个非常简单的变化,现在我的音频流继续播放,无论我在应用程序中的哪个位置。 以下是视图控制器的工作方式: 我有一个播放按钮和一个停止按钮,位于同一位置,隐藏了停止按钮。 当用户按下播放按钮时,播放按钮隐藏,显示UIActivityIndi​​catorView(`[streamer isWaiting]`) 当流开始播放时(`[streamer isPlaying]`),隐藏了'UIActivityIndi​​catorView`,并出现一个停止按钮 此外,当`[streamer isPlaying]`时,我在导航提示中显示经过的时间(mm:ss),每秒更新一次 所有上述工作每次都完美无缺。如果我离开视图(通过弹出到父视图,或导航到另一个选项卡),音频将保持播放,这正是我想要的。但是当我返回到视图时,UI看起来好像我还没有启动它(播放按钮可见,导航提示被隐藏)。如果我按下播放按钮,我会听到第二个流与第一个流同时播放。
updateProgress
似乎已经停止了(因为
self.navigationItem.prompt
不再可见),我猜测
playbackStateChanged
是“死”(不知道如何描述它)。 我花了几个小时来筛选AudioStreamer类试图找出如何保持对流的控制,但我已经筋疲力尽了。我希望有人可以告诉我我错过了什么。 正如我之前所说,我的视图控制器几乎与示例相同(请参阅上面的超链接,因为SO仍假设我是垃圾邮件发送者),只有几个与UI相关的更改。 我想简短的问题是这样的:有没有人能够实现AudioSTreamer类,弹出它的视图,然后返回并能够查看已用时间或停止流? 编辑:下面是我的视图控制器实现AudioStreamer 。H
#import <UIKit/UIKit.h>
#import <QuartzCore/CoreAnimation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <CFNetwork/CFNetwork.h>

@class AudioStreamer;


@interface RadioViewController : UIViewController
{
    IBOutlet UIButton *playButton;
    IBOutlet UIButton *stopButton;
    IBOutlet UIActivityIndicatorView *waitIndicator;

    AudioStreamer *streamer;
    NSTimer *progressUpdateTimer;

    BOOL shouldAutoStop;
}

- (IBAction)play;
- (IBAction)stop;

- (void)createStreamer;
- (void)destroyStreamer;
- (void)updateProgress:(NSTimer *)aNotification;
- (void)checkWiFi;

@end
.M
#import "AudioStreamer.h"
#import "ServerCheck.h"
#import "RadioViewController.h"

@implementation RadioViewController


- (void)viewDidLoad
{
    [[self navigationItem] setTitle:@"WXK33 162.550"];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkWiFi) name:UIApplicationDidBecomeActiveNotification object:nil];

    [super viewDidLoad];
}

- (void)viewDidAppear:(BOOL)animated
{   
    [self performSelector:@selector(checkWiFi)];

    [super viewDidAppear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    //[self performSelector:@selector(stop)];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];

    [super viewDidDisappear:animated];
}


- (void)createStreamer
{
    if ([ServerCheck serverReachable:@"audiostream.wunderground.com"])
    {
        if (streamer)
        {
            return;
        }

        [self destroyStreamer];

        NSURL *url = [NSURL URLWithString:@"http://audiostream.wunderground.com/MaffooClock/San_Angelo.mp3"];
        streamer = [[AudioStreamer alloc] initWithURL:url];

        progressUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateProgress:) userInfo:nil repeats:YES];

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackStateChanged:) name:ASStatusChangedNotification object:streamer];

    }
    else
    {
        [[self navigationController] popViewControllerAnimated:YES];
    }
}

- (IBAction)play
{
    [self createStreamer];
    [waitIndicator startAnimating];
    [streamer start];

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}

- (IBAction)stop
{
    self.navigationItem.prompt = nil;
    [streamer stop];

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}


- (void)playbackStateChanged:(NSNotification *)aNotification
{
    if ([streamer isWaiting])
    {
        [playButton setHidden:YES];
        [stopButton setHidden:YES];
        [waitIndicator startAnimating];
    }
    else if ([streamer isPlaying])
    {   
        [playButton setHidden:YES];
        [stopButton setHidden:NO];
        [waitIndicator stopAnimating];

        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    }
    else if ([streamer isIdle])
    {
        [self destroyStreamer];

        [playButton setHidden:NO];
        [stopButton setHidden:YES];
        [waitIndicator stopAnimating];
    }
}


- (void)updateProgress:(NSTimer *)updatedTimer
{
    if (streamer.bitRate > 0.0)
    {
        double progress = streamer.progress;

        double minutes = floor(progress/60);
        double seconds = trunc(progress - (minutes * 60));

        self.navigationItem.prompt = [NSString stringWithFormat:@"Elapsed: %02.0f:%02.0f",minutes,seconds];;

        if (shouldAutoStop && progress > 600)
            [self performSelector:@selector(stop)];
    }
    else
    {
        self.navigationItem.prompt = nil;
    }
}

- (void) checkWiFi
{
    if (![ServerCheck wifiAvailable])
    {
        LogInfo(@"No Wi-Fi");

        NSString * messageTitle = @"Notice";
        NSString * messageText = @"It appears that you do not have an active Wi-Fi connection.  Listening to streaming audio via cellular data may incurr additional data charges.  Streaming will automatically stop after 10 minutes.";

        UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:messageTitle message:messageText delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];

        [errorAlert show];
        [errorAlert release];

        shouldAutoStop = YES;
    }
    else
        shouldAutoStop = NO;    
}


- (void)destroyStreamer
{
    if (streamer)
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:ASStatusChangedNotification object:streamer];
        [progressUpdateTimer invalidate];
        progressUpdateTimer = nil;

        [streamer stop];
        [streamer release], streamer = nil;
    }
}


- (void)dealloc
{
    [self destroyStreamer];
    if (progressUpdateTimer)
    {
        [progressUpdateTimer invalidate], progressUpdateTimer = nil;
    }
    [super dealloc];
}

@end
    
已邀请:
事实证明,我只需要重新思考如何分配和推送视图。 “更多”选项卡显示表视图,每个单元格表示在选择该单元格时将被推送的子视图。我改变了这个视图来分配
viewDidLoad
中的所有子视图,然后简单地执行
didSelectRowAtIndexPath
内的推送,并在
dealloc
中释放子视图。 这完全解决了我的问题。感谢Jason Coco让球得分。     

要回复问题请先登录注册