2013-05-24 28 views
5

Được rồi, vì vậy tôi biết câu hỏi này đã được hỏi và hỏi. Có nhiều gợi ý tốt, nhưng tôi không thể làm được điều này như mong đợi. Tôi đang cố gắng để tạo ra một tế bào tableview có thể tự động thiết lập chiều cao của nó trên tải dựa trên html khác nhau. Những gì mọi người đề nghị là sử dụng phương pháp sau đây.Xác định chiều cao UIWebView dựa trên nội dung động của địa phương, trong một chiều cao có thể thay đổi TableViewCell

-(void)webViewDidFinishLoad:(UIWebView *)webView 

Họ nói để tính toán chiều cao hoặc sử dụng javascript như sau:

NSString *output = [webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"]; 

Hoặc làm một cái gì đó như thế này (tôi tạo này):

self.webView = webView; 
CGRect frame = webView.frame; 
frame.size.height = 1; 
webView.frame = frame; 
CGSize fittingSize = [webView sizeThatFits:CGSizeZero]; 
frame.size = fittingSize; 
webView.frame = frame; 

Cả hai phương pháp trả lại chính xác chiều cao của webview, nhưng chúng xảy ra sau khi tableview được khởi tạo. WebViewDidFinishLoad này được gọi sau phương thức heightForRowAtIndexPath. Vì vậy, khi bảng đang được xây dựng tôi không có chiều cao của tế bào. Vì vậy, sau đó mọi người nói tốt sau đó chỉ cần làm một tải lại tableview bên trong webViewDidFinishLoad của bạn mà một lần nữa không làm việc, nhưng tôi không thích điều này vì có một tụt hậu và nó làm cho di chuyển của tableview choppy khi bạn nhận được để phần đó. Làm thế nào tôi có thể sửa lỗi này? Và làm cho nó trơn tru? Tôi đã nghĩ đến có thể bằng cách nào đó xác định chiều cao webview trước khi tải xem, nhưng không chắc chắn làm thế nào tôi sẽ làm điều đó. Cũng cố gắng chuyển đổi html thành một chuỗi văn bản thuần túy, nhưng điều này dẫn đến chiều cao giả vì html có không gian và nội dung trong khi văn bản thuần túy thì không. Bất kỳ trợ giúp sẽ được đánh giá cao!

+1

Bạn có thể tải chế độ xem web ngoài màn hình sớm để có thể hoàn thành trước khi heightForRowAtIndexPath được gọi không? Ngoài ra, bạn có xác định được bản chất của độ trễ và sự xáo trộn không? Có lẽ vấn đề đó có thể được giải quyết. –

+0

Ý tưởng tuyệt vời! Đây là những gì tôi đã làm. – mikemike396

Trả lời

3

Đề xuất của tôi rất giống với @Timothy Moose, bằng cách hiển thị màn hình tắt chế độ xem web.

Cách tiếp cận tôi sẽ có được ở đây sẽ là ...

-(void)viewDidLoad 
{ 
    //Create a UIWebView and store it in a property 
    //Hook the delegate to the view controller. 
    //Load the html string to the UIWebView. 

    //The rest of your initialization 
} 

Trong trường hợp này, heightForRowAtIndexPath: của bạn sẽ vẫn có thể được gọi trước khi kết thúc việc xem web.

Bạn có thể xử lý điều đó theo một vài cách. Đây là một gợi ý.

Trong phương thức ủy nhiệm của UIWebView webViewDidFinishLoading, hãy kiểm tra để đảm bảo rằng chế độ xem web thực hiện cuộc gọi là chế độ xem web được lưu trữ trong thuộc tính của bạn. Nếu vậy, hãy gọi lại để tải lại phần (hoặc hàng) mà webview của bạn được chứa. Điều này sẽ gọi phương thức heightForRowAtIndexPath: để gọi lại, trong trường hợp này, bạn có thể lưu trữ chiều cao của webview trong cuộc gọi lại webViewDidFinishLoading.

Nếu ô tắt màn hình khi xem lần đầu tiên, ô được tạo trong cellForRowAtIndexPath:, phải có UIWebView mà bạn đã tạo trong viewDidLoad. Thực hiện việc này bằng cách thêm UIWebView vào chế độ xem nội dung của ô.

Nếu ô hiển thị trên màn hình khi lần đầu tiên hiển thị, tôi sẽ đề xuất một spinner hoạt động lần đầu tiên ô được tải và sau đó khi webview được tải xong, hãy tải lại ô bằng chế độ xem web.

+0

Câu trả lời hay! Đây dường như là giải pháp duy nhất hoạt động. Tải màn hình tắt webView và sau đó lưu trữ chiều cao hoạt động hoàn hảo. Vấn đề duy nhất tôi có là thêm webview quay lại ô trong phương thức cellForRowAtIndex. – mikemike396

4

Vào cuối ngày, bạn không thể biết chiều cao của nội dung của chế độ xem web cho đến khi nội dung tải. Và nếu cùng một chút mã đang thiết lập bảng và tải chế độ xem web, thì chế độ xem web luôn hoàn thành tải sau khi bảng đã được hiển thị.

Nếu bạn liên tục tải cùng một HTML, bạn có thể lưu vào bộ nhớ cache chiều cao, nhưng lần đầu tiên bạn sẽ gặp sự cố.

Vì vậy, cách duy nhất bạn sẽ có thể hiển thị bảng xem cuộn mà không bị thay đổi là có chiều cao ô mặc định cho đến khi webview được tải. Sau đó thay đổi nó. Nhưng bạn đã thử điều đó, sử dụng reload. Và điều đó đã bị thay đổi.

Nhưng điều gì về chiều cao của ô hoạt hình giữa chiều cao mặc định và chiều cao thực sự? Có lẽ điều đó sẽ dễ chấp nhận hơn.

Nếu bạn chỉ thực hiện thay đổi chiều cao, tôi tin rằng bạn có thể thực hiện việc này thay vì tải lại để tạo hiệu ứng thay đổi kích thước.

[tableView beginUpdates]; 
[tableView endUpdates]; 

Không cần thiết giữa hai dòng.

Có thể bạn có thể kết hợp việc này với bộ đệm ẩn chiều cao thực sự của HTML cho lần tiếp theo người dùng cuộn nó vào chế độ xem.

+0

Hoàn hảo !! hoàn hảo. Chúc mừng! –

0

Trong trường hợp của bạn, bạn có chế độ xem web trong tableviewcell, vì vậy trong heightForRowAtIndexPath đặt chiều cao ô thành chiều cao của kích thước NSAttributedString như sau.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 


    NSAttributedString *attributedText = [NSString getHTMLAttributedString:@"HTML Content"]; 
    CGSize size = CGSizeMake(300, CGFLOAT_MAX); 
    CGRect paragraphRect =  [attributedText boundingRectWithSize:size 
           options:(NSStringDrawingUsesLineFragmentOrigin) 
           context:nil]; 
    return paragraphRect.size.height; 
} 

+(NSAttributedString *) getHTMLAttributedString:(NSString *) string{ 
    NSError *errorFees=nil; 
    NSString *sourceFees = [NSString stringWithFormat: 
          @"<span style=\"font-family: 'Roboto-Light';font-size: 14px\">%@</span>",string]; 
    NSMutableAttributedString* strFees = [[NSMutableAttributedString alloc] initWithData:[sourceFees dataUsingEncoding:NSUTF8StringEncoding] 
                       options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, 
                          NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} 
                     documentAttributes:nil error:&errorFees]; 
    return strFees; 

} 
Các vấn đề liên quan