2010-03-20 26 views
21

Tôi muốn thêm chế độ xem tiêu đề vào UIWebView tương tự với thanh địa chỉ/tìm kiếm trong MobileSafari và Articles.app tuyệt vời của Sophia Teutschler. Chính xác hơn, tôi muốn tạo chế độ xem "kéo để sửa định hướng" phía trên UIWebView, giống như trong Bài viết. Các bài viết sử dụng UIWebView, vì vậy dường như có thể. Có cách nào để thực hiện việc này mà không cần phải nhúng UIWebView vào một số UIScrollView và cập nhật kích thước của nó mọi lúc, như được mô tả trong this article? Rõ ràng, tôi cần các sự kiện cuộn để có "kéo để sửa định hướng" hành xử cho phù hợp.Thêm chế độ xem tiêu đề vào UIWebView tương tự như Safari và Bài viết

+5

Bạn đã thử hỏi Sophie chưa? – hatfinch

+0

Bạn đã thử thêm một subview vào UIWebView chưa? – benzado

Trả lời

11

Sau vài attemps, tôi đã quyết định đi với giải pháp này:

Về cơ bản tôi vừa thêm UIView tiêu đề của tôi như là một subview webview.scrollview.

Để tránh tiêu đề chồng lên xem trình duyệt:

  • vòng qua tất cả [webview.scrollView subviews]
  • nhìn cho là lớn nhất, mà nên chứa các trình duyệt (những người khác cho bóng tối và dây chuyền)
  • thay đổi origin.y nó

    đây là các mã:

    CGRect browserCanvas = web.bounds; 
    for(int i=0; i< [[web.scrollView subviews] count]; i++) 
    { 
        UIView* subview = [[web.scrollView subviews] objectAtIndex:i]; 
        CGRect f = subview.frame; 
        NSLog(@"sub %d -> x:%.0f, y:%.0f, w:%.0f, h:%.0f", i, f.origin.x, f.origin.y, f.size.width, f.size.height); 
    
        if(f.origin.x == browserCanvas.origin.x && 
        f.origin.y == browserCanvas.origin.y && 
        f.size.width == browserCanvas.size.width && 
        f.size.height == browserCanvas.size.height) 
        { 
         f.origin.y = header.frame.size.height; 
         subview.frame = f; 
        } 
    } 
    
    if(![header superview]) 
    { 
        [web.scrollView addSubview:header]; 
        [web.scrollView bringSubviewToFront:header]; 
    } 
    
+3

Điều gì về việc sử dụng contentInsets của scrollView (và đặt khung của bạn y là âm)? –

+1

@kenji hoạt động tốt, như chi tiết @Manesh trong Câu trả lời khác. Ngoại trừ trường hợp khi webView của bạn có một phần tử với vị trí css được đặt thành 'fixed-top'. Nếu bạn đang mong đợi nội dung web đa dạng rộng rãi, bạn S encounter sẽ gặp phải một trang có thanh điều hướng cố định ở trên để đề xuất của @ sosergio hoạt động tốt nhất. –

0

Các bài viết có thể không sử dụng UIWebView để hiển thị văn bản bài viết chính. Để hoàn thành nhiệm vụ của bạn, UIScrollView sẽ được yêu cầu gần như chắc chắn. Thay đổi kích thước các bản xem trước của nó có thể không cần thiết. Kiểm tra các mẫu mã UIScrollView do Apple cung cấp.

+0

Các bài viết gần như chắc chắn sử dụng 'UIWebView'. – MrMage

0

Tôi không thể nói chắc chắn, nhưng Twitter dường như sử dụng UITableView để đạt được điều này. Có lẽ bạn có thể thử đặt chế độ xem của mình trong tiêu đề của chế độ xem bảng và nội dung của bạn trong ô.

Dưới đây là một ví dụ thú vị bạn có thể xem xét nhìn vào - How to make a Pull-To-Reload TableView just like Tweetie 2

+1

Tôi không gặp bất kỳ vấn đề nào khi triển khai công cụ này cho bất kỳ loại 'UITableView' nào, nhưng tôi cần có nó cho' UIWebView'. – MrMage

+2

Tôi nghĩ Adam đang đề xuất tạo một tableView với một ô tùy chỉnh duy nhất chứa UIWebView với nội dung web của bạn được tải trong đó. – slycrel

0

Enormego công bố một số mẫu mã để làm điều pull-to-refresh xảy ra:

https://github.com/enormego/EGOTableViewPullRefresh

Nó thực sự không quá phức tạp . Bạn có thể lấy thanh tiêu đề của Safari/Bài viết trong chế độ xem bảng của bạn chỉ đơn giản bằng cách tạo thanh tiêu đề và chỉ thêm nó vào UITableView làm một chế độ xem phụ. Tôi đang làm chính xác điều đó trên ứng dụng tôi đang làm việc trên bây giờ:

GBSpendingMeter *meterView = [[[GBSpendingMeter alloc] initWithFrame:CGRectMake(0,0,320,44)] autorelease]; 

// The meterView will appear pinned to the top of the table, similar to a headerView 
[self.tableView addSubview:meterView]; 

Phần khôn lanh là quan sát các sự kiện cuộn trên bàn (FYI, UITableView là một lớp con của UIScrollView vì vậy tất cả cùng một thông báo/callbacks nên hoạt động), nhưng mã mẫu mà tôi liên kết có một ví dụ tốt về cách hoạt động của mã đó.

+3

Tôi không gặp bất kỳ vấn đề nào khi triển khai công cụ này cho bất kỳ loại 'UITableView' nào, nhưng tôi cần có nó cho' UIWebView'. – MrMage

7

Tôi nghĩ giải pháp tốt nhất là thêm tiêu đề dưới dạng chế độ xem con của scrollView của UIWebView, điều chỉnh UIEdgeInsets và chức năng ủy quyền scrollViewDidScroll điều chỉnh scrollIndicatorInsets nếu cần.

Mọi giải pháp khác tôi đã tìm thấy đều không tính đến các chỉ báo cuộn.

Vì nhận được hành vi vừa phải có chút phức tạp, tôi quyết định viết một lớp để xử lý tất cả: MMWebViewWithSmartHeader. Nó vẫn còn một chút thô xung quanh các cạnh nhưng nên giúp đỡ.

+0

cảm ơn bạn rất nhiều! – HelloWorld

+0

+1, mặc dù tôi không thể làm việc với một tập 'UIImageView' làm headerView. Tôi đã phải bọc 'UIImageView' bên trong một' UIView'. – FreeAsInBeer

+0

Không tệ, nhưng xấu xí khi chế độ xem web được phóng to hoặc được quét trên trục x. Tiêu đề phải khóa trên trục x và không bị ảnh hưởng bởi phóng to thu nhỏ. – Martin

0

Hãy thử điều này:

UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(0, -100, WIN_WIDTH, 100)]; 
    redView.backgroundColor = [UIColor redColor]; 
    self.view.scrollView.contentInset = UIEdgeInsetsMake(100, 0, 0, 0); 
    [self.view.scrollView addSubview:redView]; 
    NSURLRequest *request = [NSURLRequest requestWithURL: [NSURL URLWithString:@"http://www.baidu.com"]]; 
    [self.view loadRequest:request]; 
3

Tôi thích AutoLayout đặc biệt bởi vì tôi có thể làm cho chiều cao của tiêu đề động.

Đây là mã của tôi sử dụng AutoLayout trong bộ điều khiển có tham chiếu 'headerView' cho chế độ xem tiêu đề và 'webView' cho webView.

// Function called in ViewDidLoad: 
func addHeaderToWebView(){ 
    // We load the headerView from a Nib 
    headerView = NSBundle.mainBundle().loadNibNamed(WebViewHeader.nibName, owner: self, options: nil).first as! WebViewHeader 

    headerView.translatesAutoresizingMaskIntoConstraints = false 

    webView.scrollView.addSubview(headerView) 

    // the constraints 
    let topConstraint = NSLayoutConstraint(item: headerView, attribute: .Bottom, relatedBy: .Equal, toItem: webView.scrollView, attribute: .Top, multiplier: 1, constant: 0) 
    let leftConstraint = NSLayoutConstraint(item: headerView, attribute: .Leading, relatedBy: .Equal, toItem: webView, attribute: .Leading, multiplier: 1, constant: 0) 
    let rightConstraint = NSLayoutConstraint(item: headerView, attribute: .Trailing, relatedBy: .Equal, toItem: webView, attribute: .Trailing, multiplier: 1, constant: 0) 

    // we add the constraints 
    webView.scrollView.addConstraints([topConstraint]) 
    webView.addConstraints([leftConstraint, rightConstraint]) 
} 

// Function called in viewWillLayoutSubviews: to update the scrollview of the webView content inset 
func updateWebViewScrollViewContentInset(){ 
    webView.scrollView.contentInset = UIEdgeInsetsMake(headerView.frame.height, 0, 0, 0) 
} 
Các vấn đề liên quan