Добавление представления заголовка к UIWebView, аналогичному Safari и статьям - PullRequest
21 голосов
/ 20 марта 2010

Я бы хотел добавить представление заголовка к UIWebView, похожему на адресную строку / строку поиска в MobileSafari и отличном Articles.app от Софии Тойчлер. Точнее, я хотел бы создать представление «тянуть, чтобы исправить ориентацию» над UIWebView, как в статьях. Статьи действительно используют UIWebView, так что это кажется возможным. Есть ли способ сделать это, не вставляя UIWebView в UIScrollView и постоянно обновляя его размер, как описано в этой статье ? Очевидно, мне нужны события прокрутки, чтобы "тянуть, чтобы исправить ориентацию" вести себя соответственно.

Ответы [ 7 ]

11 голосов
/ 20 ноября 2011

После нескольких попыток я решил воспользоваться этим решением:

По сути, я только что добавил свой заголовок UIView в качестве подпредставления webview.scrollview.

Чтобы заголовок не перекрывал представление браузера:

  • цикл по всем [webview.scrollView подпредставлениям]
  • искать самое большое, который должен содержать браузер (остальные для теней и линий)
  • изменить свое происхождение.y

    вот код:

    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];
    }
    
7 голосов
/ 07 августа 2012

Я думаю, что лучшее решение - добавить заголовок как подпредставление scrollView вашего UIWebView, настроить UIEdgeInsets, а в функции делегата scrollViewDidScroll настроить scrollIndicatorInsets при необходимости.

Все остальные найденные мной решения не учитывали показатели прокрутки.

Поскольку правильное поведение имеет некоторую сложность, я решил написать класс для его обработки: MMWebViewWithSmartHeader . Это все еще немного шероховато по краям, но должно помочь.

3 голосов
/ 10 ноября 2015

Мне особенно нравится AutoLayout, потому что я могу сделать динамически высоту заголовка.

Это мой код, использующий AutoLayout в контроллере со ссылкой «headerView» на представление заголовка и «webView» на 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)
}
0 голосов
/ 09 января 2015

Попробуйте это:

    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];
0 голосов
/ 05 ноября 2010

Enormego опубликовал пример кода, чтобы сделать процесс обновления:

https://github.com/enormego/EGOTableViewPullRefresh

Это действительно не так сложно. Вы можете получить панель заголовка в стиле Safari / Articles в виде таблицы, просто создав панель заголовка и просто добавив ее в UITableView в качестве подпредставления. Я делаю именно это в приложении, над которым работаю сейчас:

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];

Сложная задача - наблюдать за событиями прокрутки в таблице (FYI, UITableView является подклассом UIScrollView, поэтому все те же уведомления / обратные вызовы должны работать), но пример кода, с которым я связан, имеет хороший пример того, как это работает.

0 голосов
/ 05 ноября 2010

Не могу сказать наверняка, но Twitter, похоже, использует UITableView для достижения этой цели. Возможно, вы можете попытаться поместить свое представление в заголовок табличного представления, а свое содержимое - в ячейку.

Вот интересный пример, который вы могли бы рассмотреть, глядя на Как создать таблицу Pull-To-Reload, как Tweetie 2

0 голосов
/ 04 ноября 2010

Статьи могут не использовать UIWebView для отображения основного текста статьи.Чтобы выполнить вашу задачу, UIScrollView потребуется почти наверняка.Изменение размера его подпредставлений может не быть необходимым.Ознакомьтесь с примерами кода UIScrollView, предоставленными Apple.

...