2017-08-13 54 views
0

背景:我有一個UITableView,它最初加載了一些標準的UITableViewCells。當單擊其中一個時,表被重新加載,但被單擊的單元格變成了名爲'RecordingTableCell'的自定義子類,它具有2個UILabels,一個UIButton和一個UISlider。目前這工作正常。UISlider&UILabels自定義tableviewcell不更新與avaudioplayer直到第二次播放音頻

當按下按鈕時,會導致設置AVAudioPlayer並播放聲音文件。但是,這樣做的方法([self setupAudio])也獲得了2個UILabels和UISlider,以便它們可以隨音頻的進度而更新(我不確定是否以正確的方式得到它們)。

當按下首次播放按鈕,音頻播放,但滑塊或標籤不發生任何變化。但是,音頻結束後(即一旦調用audioPlayerDidFinishPlaying),如果再次按下播放按鈕,則所有內容都按原樣運行。

The code running in the simulator

下面是代碼:(!遺憾的大塊)

... 

-(void)setupAudio 
{ 
    //Get path 
    recordingPaths = [[NSUserDefaults standardUserDefaults] objectForKey:@"recordingPaths"]; 
    recordedAudioURL = [NSURL URLWithString:recordingPaths[selectedRowIndex.row]]; 

    NSError *audioError; 
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:[self recordedAudioURL] error:&audioError]; 
    player.delegate = self; 

    [player prepareToPlay]; 

    recordingCurrentCell = (RecordingTableCell *)[self.tableView viewWithTag:REC_TABLE_CELL_TAG]; 

    //The following are subviews of recordingTableCell 
    currentTimeLabel = [recordingCurrentCell currentTimeLabel]; 
    totalTimeLabel = [recordingCurrentCell totalTimeLabel]; 
    slider = [recordingCurrentCell progressSlider]; 

    //Setup slider & labels 
    slider.maximumValue = [player duration]; 
    totalTimeLabel.text = [NSString stringWithFormat:@"%.1f", player.duration]; 

    slider.value = 0.0; 
    currentTimeLabel.text = [NSString stringWithFormat:@"%.1f", slider.value]; 
} 

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 

    selectedRowIndex = indexPath; 
    rowSelected=YES; 

    //Update the table so that the row with an indexPath equal to 'selectedRowIndex' becomes a custom subclass of UITableViewCell 
    [tableView beginUpdates]; 
    [self.tableView reloadData]; 
    [tableView endUpdates]; 

    if(!player) 
    { 
     if(selectedRowIndex.row!=indexPath.row) 
     { 

      [[self player] stop]; 
      player=nil; 

      //Change button on selected cell to the 'play' image 
      [actionButton setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal]; 

      //If the NSTimer is still going, invalidate it 
      if(timer) 
      { 
       [timer invalidate]; 
       timer = nil; 
      } 
     } 
    } 
    [self setupAudio]; 
} 

//This is hooked up to the button on the custom tableviewcell 
- (IBAction)actionButtonPressed:(id)sender 
{ 
    actionButton = (UIButton *)sender; 

    if(!player.playing) 
    { 
     [actionButton setImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal]; 

     [timer invalidate]; 
     timer = nil; 

     [player play]; 
     timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES]; 
     [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 
    } 
    else 
    { 
     if(timer) 
     { 
      [timer invalidate]; 
      timer = nil; 
     } 
     [actionButton setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal]; 
     [player pause]; 
    } 
} 

//This is connected to the slider on the custom tableviewcell. 
- (IBAction)slide:(id)sender 
{ 
    if(player) 
    { 
     player.currentTime = slider.value; 
    } 
    currentTimeLabel.text = [NSString stringWithFormat:@"%.1f", slider.value]; 
} 


- (void)updateTime:(NSTimer *)timer 
{ 
    if(player) 
    { 
     slider.value = player.currentTime; 
     currentTimeLabel.text = [NSString stringWithFormat:@"%.1f", slider.value]; 
    } 
} 


- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag 
{ 
    if(timer) 
    { 
     [timer invalidate]; 
     timer = nil; 
    } 

    [self setupAudio]; 
    [actionButton setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal]; 
} 

我已經試過移動周圍的一些位,我不知道如果我要去在[self setupAudio]中獲取'RecordingTableCell'子視圖時出錯,或者音頻播放器設置錯誤。

任何幫助將不勝感激!

回答

0

我也不太清楚,如果這是去了解它的正確方法(即有可能是一個更根本的,我在這裏失蹤),但我設法通過創建一個布爾變量來保存是否解決問題它是第一次用於記錄設置的AVAudioPlayer,如果是這樣在actionButtonPressed方法,重新實例化子視圖。

2

我認爲球員的電流/持續時間爲雙類型,你可以用下面的方法來得到它作爲一個字符串:

func getTimeString(from duration:Double) -> String{ 

     let hours = Int(duration/3600) 
     let minutes = Int(duration/60) % 60 
     let seconds = Int(duration.truncatingRemainder(dividingBy: 60)) 
     if hours > 0 { 
      return String(format: "%:%02i:%02i", arguments: [hours,minutes,seconds]) 
     }else { 
      return String(format: "%02i:%02i", arguments: [minutes,seconds]) 
     } 

    } 

當前時間字符串:

func getCurrentTimeAsString() -> String{ 

     guard let time = player?.currentTime else { 
      return "00:00" 
     } 

     return getTimeString(from: time) 
    } 

總時間字符串:

func getDurationAsString() -> String{ 

     guard let time = player?.duration else { 
      return "00:00" 
     } 
     return getTimeString(from: time) 
    } 

獲取過程值:

func getProgressValue()->Float{ 
     var theCurrentTime = 0.0 
     var theDuration = 0.0 
     if let currentTime = player?.currentTime,let duration = player?.duration { 
      theCurrentTime = currentTime 
      theDuration = duration 
     } 
     return Float(theCurrentTime/theDuration) 
    } 

而且你需要使用一個定時器來更新當前時間標籤的文字,不要忘記停止計時器。

timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true, block: {[unowned self] (timer:Timer) in 
       self.updateUIWithTimer() 
      }) 

    func updateUIWithTimer(){ 

     currentTimeLabel.text = getCurrentTimeAsString() 

     timeSlider.value = getProgressValue() 

    }   
+0

謝謝您的回覆(+1),我測試你的代碼在斯威夫特和它的,因爲它適用於自己的,然而,當合併入我原來objc我仍然會得到同樣的錯誤UISlider&UILabels只會在第二場比賽後作出迴應。 –