2009-03-14 2 views
16

HTML 인 텍스트가있는 테이블을 만들고 있으므로 사용자 정의 테이블 셀의 하위 뷰로 UIWebView를 사용하고 있습니다. 이미 한 가지 문제에 부딪 혔습니다. 테이블에서 아래로 스크롤하면 UIWebViews를 업데이트하는 데 걸리는 시간이 단축됩니다. 예를 들어 번호가 1, 2 및 3 인 행에서 셀을 볼 수 있습니다. 아래로 스크롤하면 8, 9 및 10이됩니다. 잠시 동안 셀 # 8에서 볼 수있는 UIWebView의 내용은 셀 # 1의 컨텐츠, 셀 # 9의 컨텐츠는 셀 # 2의 컨텐츠 등이었습니다.Table Cell에서 UIWebView는 어떻게 사용합니까?

UIWebViews가 텍스트를 천천히 렌더링한다는 문제가 있다는 것을 알았습니다. 대신에 테이블이 cellForRowAtIndexPath를 수신 할 때까지 기다릴 수있는 대신 UIWebView에 내용을 미리로드하는 것이 좋습니다. 이제는 WebView의 텍스트 콘텐트를 갖기 전의 Domain Object가 있습니다.하지만 이제는 실제로 UIWebView 자체에 대한 참조가 있습니다.

하지만 이제는 UIWebView의 일부 내용이 렌더링되고 UIWebView가 회색 상자로만 표시됩니다. 회색 상자를 터치하면 실제로 터치가 수신되고 WebView가 업데이트됩니다. 예를 들어 링크를 터치하면 (상자가 회색이고 행운을 빕니다) 링크를 터치하면됩니다. 링크 된 페이지가 요청되어 제대로 표시됩니다.

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { 
if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) { 
      // I suppose this isn't necessary since I am just getting it from the 
      // Domain Object anyway 
    content = [[UIWebView alloc] initWithFrame:CGRectZero]; 
    content.backgroundColor = [UIColor blackColor]; 
    [self addSubview:content]; 
    [content release]; 
} 
return self; 
} 

// called by cellForRowAtIndexPath 
- (void)setMyDomainObject:(MyDomainObject*)anObject { 
UIWebView *contentWebView = anObject.contentWebView; 
int contentIndex = [self.subviews indexOfObject:content]; 
[self insertSubview:contentWebView atIndex:contentIndex]; 
} 

답변

9

이 문제를 해결하는 한 가지 방법은 서로 다른 글꼴을 가진 여러 개의 UILabels를 사용하는 것입니다. 그런 다음 셀 안에 전략적으로 배치하여 인접한 텍스트처럼 보이게 만듭니다. 나는 이것을 아주 좋은 결과를 가진 UITableView에서 보았다.

또 다른 성능 문제는 UItableViewCell 및 init 메소드를 무시하는 것일 수 있습니다. 이것은 거의 항상 UITableView의 성능 저하를 초래합니다. 대신 일반 UITableViewCell 인스턴스를 사용하고 하위 뷰를 contentView에 추가하면됩니다.

이것은 매트 갤러거 (Matt Gallagher)의 Easy Custom UITableView Drawing에 의해 광범위하게 다뤄졌습니다.

설명 된 또 다른 방법은 스타일이 지정된 텍스트를 제공 할 수있는 Three20을 사용하는 것이 었습니다.

현재 시도중인 것은 UIWebview로 수행 할 수 없습니다.

사전로드가 도움이되지 않습니다. UIWebviews가 화면 밖으로 렌더링 될 때 UI 속도가 느려집니다. iPhone에서 게으른 로딩을 항상 연습해야합니다.

UIWebviews를 UITableView에 넣는 것은 잠재적으로 허용 할 수없는 성능에 영향을줍니다. 목표 달성을 위해 다른 수단을 사용해야 할 것입니다.

유감스럽게도 NSAttributedString은 UIKit에서 사용할 수 없으므로 쉽게 문제를 해결할 수 있습니다.

+0

나는 이것이 UIWebView로 할 수있는 것이 아니라는 사실을이 사실로 받아 들였다. 개인적으로 필자는이 기능을 포기하고 있지만 곧 다시 방문 할 것입니다. TableView를 사용하는 대신 HTML과 CSS를 사용하여 시뮬레이트하고 하나의 WebView에 넣는 것입니다. 그런 다음 WebViewDelegate를 사용하여 링크에서 "가로 채기"클릭을 정렬하고 다른 웹 컨텐트를 표시할지 또는 내 응용 프로그램에서 다른 작업을 수행할지 결정합니다. – bpapa

0

테이블 셀 하위 클래스에서 -prepareForReuse 메소드를 재정의 한 적이 있습니까? 스크롤 할 때 셀이 업데이트되지 않는 것처럼 보이면 재사용 가능한 셀의 내용이 지워지고 재설정되지 않을 가능성이 있습니다.

1

'setRowAtIndexPath에 의해 호출되었습니다'라고 말하면 행이 표시되고 셀을 만들어야 할 때 호출되는 UITableView 메서드 인 'cellForRowAtIndexPath'를 의미 할 수 있습니다. 이 메서드에서 셀 내용을 제대로 초기화하고 업데이트하는지 확인하십시오.

+0

예, 저는 질문을 쓰는 가장 좋은 방법이 아닌 메모리에서이 작업을 수행했습니다. – bpapa

+0

'웹보기를 스크롤하지 않아도 업데이트되지 않습니다'라는 것을 명확히 할 수 있습니까? 웹보기 내에서 스크롤하거나 테이블보기를 아래로 스크롤하고 있습니까? 어떤 내용이 webview에 있으며 무엇을 변경해야합니까? – Akusete

+0

질문의 세 번째 단락은 내가 보는 것을 더 잘 설명합니다. – bpapa

2

이 질문에 대한 답변이 원래 질문에 답하고 있지 않지만 한 걸음 뒤로 물러서 더 큰 그림을보고 테이블 셀에 하이퍼 링크를 표시하려고하면 클릭하면 열립니다 웹 브라우저? 표 셀에 링크 모양이나 힌트가있는 스타일이 지정된 텍스트를 표시했지만 링크를 탭할 수있는 전체 화면 웹보기가있는 별도의 화면을 여는 경우에도 동일합니까?

4

웹보기의 내용은 스타일 텍스트 또는 당신은 Three20 프로젝트에서 살펴 봐야 할 수 있습니다 하이퍼 링크로 제한되어있는 경우 : http://github.com/joehewitt/three20/tree/master

TTStyledText 클래스는 내용의 <b>, <i>, <img>, and <a> 태그에 대한 지원을하고있다. 아마도 webviews보다 더 가볍습니다.

0

WebView는 viewDidLoad()가 발생한 후 로딩을 시작하지 않으면 렌더링되지 않습니다.

+1

UIWebView는 제어가 메인 RunLoop로 돌아온 후에 렌더링을 수행하는 것으로 보이므로 JavaScript를 실행하려고하면 [viewDidLoad] 또는 - [viewWillAppear]에서 수행 할 수 없습니다. 웹보기가 완료되면 웹보기 대리자의 메소드에서이 작업을 수행 할 수 있습니다. – lucius

6

내 업데이트 된 답변은 다음과 같습니다. 하나의 큰 UIWebView를 사용하여 내 트위터 클라이언트 앱의 표 셀 안에 스타일이 지정된 텍스트를 넣을 테이블을 구현했습니다 (소스를 사용할 수 있음). HelTweetica HTML과 CSS로 레이아웃을 만드는 방법을 이해한다면 꽤 잘 작동합니다.

NSMutableString을 만들고 문서를 구성하는 HTML 행을 추가하기 만하면됩니다. 앱의 샌드 박스에있는 CSS 파일과 같은 외부 파일을 참조 할 수 있습니다. 웹보기 대리인이 IBAction의 대체 차단 및 처리 할 수 ​​있습니다 : "//file.txt youraction"당신과 같은 사용자 정의 URL 작업을 설정할 수 있습니다

- (void) refreshWebView { 
    TwitterAccount *account = [twitter currentAccount]; 
    NSMutableString *html = [[NSMutableString alloc] init]; 
    // Open html and head tags 
    [html appendString:@"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"]; 
    [html appendString:@"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"]; 
    [html appendString:@"<head>\n"]; 
    [html appendString:@"<meta name='viewport' content='width=device-width' />"]; 
    [html appendString:@"<link href='style-ipad.css' rel='styleSheet' type='text/css' />"]; 
    [html appendString:@"<script language='JavaScript' src='functions.js'></script>"]; 

    // Body 
    [html appendString:@"</head><body><div class='artboard'>"]; 

    // [...] 

    // Close artboard div, body. and html tags 
    [html appendString:@"</div></body></html>\n"]; 

    NSURL *baseURL = [NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]]; 
    [self.webView loadHTMLString:html baseURL:baseURL]; 
    [html release]; 
} 

을 그리고 당신은 자바 스크립트를 사용하여 페이지의 일부를 다시로드 할 수 있습니다 :

- (void) refreshTabArea { 
    NSString *html = [self stringByEscapingQuotes: [self tabAreaHTML]]; 
    NSString *js = [NSString stringWithFormat: @"document.getElementById(\"tab_area\").innerHTML = \"%@\";", html]; 
    [self.webView stringByEvaluatingJavaScriptFromString:js]; 
} 
관련 문제