2010-11-10 54 views
2

我想獲得一個UIWebView動態更新,有點像卡拉OK盒,因爲它迭代了一個while循環。 tts引擎所說的單詞應該是橙色的(或者在html,.style2中)。我的UIWebView懶散地重新加載。當我希望顯示數據時,如何重新加載/刷新?

正在發生的事情,然而,就是在一個UIWebView不通過htmlKaraoke串的每次迭代更新它的顯示,但只有最後一個while循環。 UIWebView似乎以懶惰的方式重新加載,並在更新顯示之前等待while循環完成。我在代碼中包含了所有不同的方法,我試圖繞過這個(setNeedsDisplay,setNeedsLayout,重置htmlKaraoke字符串,重新加載UIWebView),但我似乎無法讓它做我想做的事情。

HTML代碼的更新像它應該(在橙色口語),但Webview是不是反映了這一點。

我怎樣才能讓web視圖到htmlKaraoke串的每次更新之後更新?

i = 0; 
NSString *htmlHead    = @"<html><head><style type='text/css'><!-- .style1 { font-size: 24px; font-weight: bold; font-family: Helvetica; } .style2 {color: #FF9900} --> </style></head><body><span class='style1'>"; 
NSString *htmlFoot    = @"</span></body></html>"; 
NSString *htmlEmpHead   = @"<span class='style2'>"; 
NSString *htmlEmpFoot   = @"</span>"; 
NSMutableString *htmlKaraoke = [[NSMutableString alloc] init]; 

while(i <= wordWeAreUpToInt){ 
    //wait until the tts is finished talking. 
    if(![[fliteEngine audioPlayer] isPlaying]){ 
     //NSLog(@"flite is finished!"); 

     //Add the word and highlight in the karaoke 

      /* Clear the html string 
       Make a for loop, where n = 0, n<i, n++ 
        append black word 
       when for loop ends, and n == i, add an emph word (n==i when i is the currently spoken word). 
      */ 
     [karaokeWebView loadHTMLString:@" " baseURL:nil]; 
     [karaokeWebView reload]; //doesn't do anything. These two lines are a waste of breath. 

     [htmlKaraoke setString:htmlHead]; 
     for (int n = 0; n<i; n++) { 
      [htmlKaraoke appendString:[wordsArray objectAtIndex:n]]; 
      [htmlKaraoke appendString:@" "]; 
     } 
     [htmlKaraoke appendString:htmlEmpHead]; 
     [htmlKaraoke appendString:[wordsArray objectAtIndex:i]]; 
     [htmlKaraoke appendString:@" "]; 
     [htmlKaraoke appendString:htmlEmpFoot]; 
     NSLog(@"Emphasis: %@", [wordsArray objectAtIndex:i]);   
     [htmlKaraoke appendString:htmlFoot]; 


     NSLog(@"htmlKaraoke: %@", htmlKaraoke); 

     [karaokeWebView loadHTMLString:htmlKaraoke baseURL:nil]; 
     [karaokeWebView setNeedsDisplay]; 
     [karaokeWebView setNeedsLayout]; //getting desperate....! 

     //speak the word 
     [self readSentence:[wordsArray objectAtIndex:i]]; 
     i++; 
    } 
} 

[htmlKaraoke release]; 
wordWeAreUpToInt++; 
} 

回答

3

我覺得你的問題是,一個UIWebView只呈現後控制返回到主NSRunLoop /事件循環的觀點。因此,如果您在上面的while循環中進行所有更新,那麼只有最後一個字符串會被加載,因爲它從來沒有機會加載其他字符(&,因此只會使用最後一個加載請求)。

您將需要退出您編寫的任何代碼(不只是此方法,還包括觸發此方法的任何內容等),並將控制權返還給操作系統,然後UIWebView將使用您的更改進行更新。

假設任何對象的代碼是仍然控制返回後身邊時,你可以通過添加這對你的類測試了這一點:

- (void)loadHTMLString:(NSString *)string { 
    [karaokeWebView loadHTMLString:string baseURL:nil]; 
} 

,然後改變你的-[loadHTMLString:baseURL:]調用到:

[self performSelector:@selector(loadHTMLString:) withObject:htmlKaraoke afterDelay:_delay_increasing_by_a_second_for_each_string]; 

還有更多主「事件循環」的「的iOS應用程序編程指南」的「Application Life Cycle」部分。

+0

好的,這是有道理的。任何人都可以想出另一種方法來製作/實現它嗎?此操作是單擊按鈕的結果。 – glenstorey 2010-11-10 02:27:45

+0

我剛編輯我的答案。在那裏給出示例測試代碼。對於通過絃樂進行動畫製作,您只需稍微增加延遲(因此第一個延遲爲1秒,然後是2秒,然後是3等)。 – 2010-11-10 02:40:35

+0

哦,注意你可能需要在每個點傳入一個字符串的_copy_,否則你只會傳遞一個指向可變字符串的指針(隨着循環的進行而改變)。通過更改'withObject:htmlKaraoke'位來實現。 – 2010-11-10 02:49:05