【问题标题】:Create Custom UIView with Custom WebView and UISearchContoller使用自定义 WebView 和 UISearchContoller 创建自定义 UIView
【发布时间】:2016-06-27 00:05:57
【问题描述】:

我正在开发一个 iOS 应用程序,我创建了一个 UIViewController 来放置我的组件,它运行良好。 现在我正在尝试创建一个自定义 UIView 并将我的 WebView 和我的 SearchController 放入 .我花了很多时间都没有成功。

这是我的.m 文件,希望有人能帮助我:

#import "HomeViewController.h"


#define widthtScreen  [UIScreen mainScreen].bounds.size.width
#define heightScreen  [UIScreen mainScreen].bounds.size.height


@interface HomeViewController () <UISearchResultsUpdating,UISearchBarDelegate,UIBarPositioningDelegate,UITableViewDataSource,UITableViewDelegate,MapWebViewDelegate>

@property(strong,nonatomic) MapWebView *webView;

@property (nonatomic) UIButton  *btnGeolocate;


@property (nonatomic, strong) UISearchController *searchController;

@end

@implementation HomeViewController{
    NSMutableArray *placesList;
    BOOL isSearching;
}



-(void)loadView
{
    [super loadView];
    self.webView = [[MapWebView alloc] initWithFrame:CGRectMake(0, -100, widthtScreen, heightScreen+100)];
    self.webView.mapWebViewDelegate = self;
    [self.view addSubview:self.webView];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.navigationItem.hidesBackButton = YES;
    mainDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
    placesList = [[NSMutableArray alloc] init];
    [self initializeSearchController];
    mainDelegate.webView = self.webView;


    self.btnGeolocate = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width-75,550,60,60)];
    self.btnGeolocate.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    [self.btnGeolocate setBackgroundImage:[UIImage imageNamed:@"geo.png"]
                                 forState:UIControlStateNormal];
    [self.btnGeolocate addTarget:self action:@selector(btnGeolocatePressed:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.btnGeolocate];

    mainDelegate.btnZoomIn = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width-80,620,30,30)];
    mainDelegate.btnZoomIn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    [mainDelegate.btnZoomIn setBackgroundColor:[UIColor blackColor]];
    [mainDelegate.btnZoomIn addTarget:self action:@selector(btnZoomInPressed:) forControlEvents:UIControlEventTouchUpInside];
    mainDelegate.btnZoomIn.tag=1;
    UIImage *btnImage = [UIImage imageNamed:@"plus.png"];
    [mainDelegate.btnZoomIn setImage:btnImage forState:UIControlStateNormal];
    [self.view addSubview:mainDelegate.btnZoomIn];

    mainDelegate.btnZoomOut = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width-40,620,30,30)];
    mainDelegate.btnZoomOut.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    [mainDelegate.btnZoomOut setBackgroundColor:[UIColor blackColor]];
    [mainDelegate.btnZoomOut addTarget:self action:@selector(btnZoomOutPressed:) forControlEvents:UIControlEventTouchUpInside];
    mainDelegate.btnZoomOut.tag=1;
    UIImage *btnImage2 = [UIImage imageNamed:@"minus.png"];
    [mainDelegate.btnZoomOut setImage:btnImage2 forState:UIControlStateNormal];
    [self.view addSubview:mainDelegate.btnZoomOut];
}

- (BOOL)slideNavigationControllerShouldDisplayLeftMenu
{
    return YES;
}

- (BOOL)slideNavigationControllerShouldDisplayRightMenu
{
    return YES;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSLog(@"number :%lu",(unsigned long)[placesList count]);
    return [placesList count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    SuggestResultObject *sro = [SuggestResultObject new];
    sro = [placesList objectAtIndex:indexPath.row];
    cell.textLabel.text = sro.textPlace;
    return cell;
}

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{
    self.navigationItem.leftBarButtonItem = nil;
    self.navigationItem.rightBarButtonItem =nil;
    return true;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    self.navigationItem.leftBarButtonItem = mainDelegate.leftBarButtonItem;
    self.navigationItem.rightBarButtonItem = mainDelegate.rightBarButtonItem;
    SuggestResultObject *sro = [SuggestResultObject new];
    sro = [placesList objectAtIndex:indexPath.row];
    self.searchController.active = false;
    NSString *function = [[NSString alloc] initWithFormat: @"MobileManager.getInstance().moveToLocation(\"%@\",\"%@\")", sro.latPlace,sro.lonPlace];
    [_webView evaluateJavaScript:function completionHandler:nil];
}



- (void)jsRun:(NSString *) searchText {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSString *function = [[NSString alloc] initWithFormat: @"MobileManager.getInstance().setSuggest(\"%@\")", searchText];
        [_webView evaluateJavaScript:function completionHandler:nil];
    });
}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
    isSearching = YES;
}

- (void)initializeSearchController {
    UITableViewController *searchResultsController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
    searchResultsController.tableView.dataSource = self;
    searchResultsController.tableView.delegate = self;
    self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
    self.definesPresentationContext = YES;
    self.searchController.hidesNavigationBarDuringPresentation = false;
    self.searchController.accessibilityElementsHidden= true;
    self.searchController.dimsBackgroundDuringPresentation = true;
    self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
    self.navigationItem.titleView = self.searchController.searchBar;
    self.searchController.searchResultsUpdater = self;
    self.searchController.searchBar.delegate = self;
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    self.navigationItem.leftBarButtonItem = mainDelegate.leftBarButtonItem;
    self.navigationItem.rightBarButtonItem = mainDelegate.rightBarButtonItem;
    NSLog(@"Cancel clicked");
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    [placesList removeAllObjects];
}


-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
    [placesList removeAllObjects];
    if([searchController.searchBar.text length] != 0) {
        isSearching = YES;
        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
        [self jsRun:searchController.searchBar.text];
    }
    else {
        isSearching = NO;
        [((UITableViewController *)self.searchController.searchResultsController).tableView reloadData];
    }
}

-(void) btnGeolocatePressed : (id) sender{
}

-(void) btnZoomInPressed : (id) sender{
    [_webView evaluateJavaScript:@"MobileManager.getInstance().zoomIn();" completionHandler:nil];
}

-(void) btnZoomOutPressed : (id) sender{
    [_webView evaluateJavaScript:@"MobileManager.getInstance().zoomOut();" completionHandler:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)searchResult:(NSArray*)dataArray{
    SuggestResultObject *sro = [SuggestResultObject new];
    sro.textPlace = [dataArray objectAtIndex:0];
    sro.lonPlace = [dataArray objectAtIndex:1];
    sro.latPlace = [dataArray objectAtIndex:2];
    [placesList addObject:sro];
    [((UITableViewController *)self.searchController.searchResultsController).tableView reloadData];
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
@end

【问题讨论】:

  • 嗨,OP,如果您真的告诉我们问题出在哪里,而不是:“这是我的代码,帮助”,将会有所帮助。
  • 问题是我试图将带有 uisearchcontroller 的自定义 webview 放入自定义 uiview 然后在 uiviewcontroller 中调用它,但我不能这样做,因为在视图中我不能使用导航控制器,即使我手动创建它也不起作用
  • @OP;您希望将 UIWebView 和 UISearchController 嵌入到嵌入 NavigationController 的 UIViewController 中吗?或者您是否希望将 UIWebView 和 UISearchController 嵌入在嵌入 UIView 的 NavigationController 中?
  • 我想要一个 UIWebView 和 UISearchController 嵌入到 UIView 中
  • 当我调用 UIViewController 时,导航控制器应该没有问题

标签: ios objective-c uiview uiwebview uisearchcontroller


【解决方案1】:

屏幕截图(不知道如何在 stackoverflow 上缩放图像。OSX 以 Retina 格式拍摄图像并且它们相当大!提前抱歉!):

http://i.imgur.com/15qxDpc.png

http://i.imgur.com/QHduP07.png

它是如何工作的?创建一个UIView 和两个子视图:UITableViewUIWebView。适当地约束它们。

使用nil SearchResultsController 创建UISearchController 作为init 方法的参数。

这让搜索控制器知道结果将是 显示在当前控制器/视图中。

接下来我们为UISearchController 设置代理并创建 过滤功能。

现在我们已经创建了视图,我们需要一个UIViewController 来 测试它。我们可以将搜索栏添加到 tableView 标题或 到 NavigationController 如果有的话..

下面,我选择将它添加到UINavigationController 和我 告诉UISearchController 不要隐藏导航栏 演示文稿。

这样,结果会显示在当前视图中而不隐藏 导航栏。

然后您可以使用隐藏和屏幕外的 webview 来执行 无论您使用什么 javascript 搜索..

不过,更好的办法是使用JSContext 来执行 Javascript 而不是UIWebViewUIWebView的优势 是您可以解析 HTML 并修改 JSContext 的 DOM 不允许。

无论如何..

这是我为 UIView 编写的代码,其中包含 UISearchControllerUIWebView.. 然后将其添加到 UIViewController 嵌入在 UINavigationController 中。

//
//  SearchView.h
//  StackOverflow
//
//  Created by Brandon T on 2016-06-26.
//  Copyright © 2016 XIO. All rights reserved.
//

#import <UIKit/UIKit.h>

@class SearchView;

@protocol SearchViewDelegate <UISearchBarDelegate>
- (void)didSelectRowAtIndexPath:(SearchView *)searchView tableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath;
@end

@interface SearchView : UIView
@property (nonatomic, weak) id<SearchViewDelegate> delegate;
- (UISearchBar *)getSearchBar;
- (UIWebView *)getWebView;
@end


//
//  SearchView.m
//  StackOverflow
//
//  Created by Brandon T on 2016-06-26.
//  Copyright © 2016 XIO. All rights reserved.
//

#import "SearchView.h"

#define kTableViewCellIdentifier @"kTableViewCellIdentifier"

@interface SearchView() <UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating>
@property (nonatomic, strong) UIWebView *webView;
@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSArray *dataSource;
@property (nonatomic, strong) NSArray *searchResults;
@end

@implementation SearchView

- (instancetype)init {
    if (self = [super init]) {

        [self setupData];
        [self initControls];
        [self themeControls];
        [self registerCells];
        [self doLayout];
    }
    return self;
}

- (UISearchBar *)getSearchBar {
    return _searchController.searchBar;
}

- (UIWebView *)getWebView {
    return _webView;
}

- (void)setDelegate:(id<SearchViewDelegate>)delegate {
    _delegate = delegate;
    _searchController.searchBar.delegate = delegate;
}

- (void)setupData {
    //Begin fake data

    _dataSource = @[@"Cat", @"Dog", @"Bird", @"Parrot", @"Rabbit", @"Racoon", @"Rat", @"Hamster", @"Pig", @"Cow"];

    //End fake data


    _searchResults = [_dataSource copy];
}

- (void)initControls {
    _webView = [[UIWebView alloc] init];
    _searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
}

- (void)themeControls {
    [_webView setHidden:YES];

    [_tableView setDelegate:self];
    [_tableView setDataSource:self];

    _searchController.searchResultsUpdater = self;
    _searchController.dimsBackgroundDuringPresentation = false;
    _searchController.definesPresentationContext = true;
    _searchController.hidesNavigationBarDuringPresentation = false;
}

- (void)registerCells {
    [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kTableViewCellIdentifier];
}

- (void)doLayout {
    [self addSubview:_webView];
    [self addSubview:_tableView];

    NSDictionary *views = @{@"webView":_webView, @"tableView": _tableView};
    NSMutableArray *constraints = [[NSMutableArray alloc] init];

    [constraints addObject:[NSString stringWithFormat:@"H:|-(%d)-[webView]-(%d)-|", 0, 0]];
    [constraints addObject:[NSString stringWithFormat:@"H:|-(%d)-[tableView]-(%d)-|", 0, 0]];

    [constraints addObject:[NSString stringWithFormat:@"V:|-(%d)-[webView(%d)]-(%d)-[tableView]-(%d)-|", -100, 100, 0, 0]];

    for (NSString *constraint in constraints) {
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:constraint options:0 metrics:nil views:views]];
    }

    for (UIView *view in self.subviews) {
        [view setTranslatesAutoresizingMaskIntoConstraints:NO];
    }
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _searchController.active && _searchController.searchBar.text.length > 0 ? [_searchResults count] : [_dataSource count];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 50;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kTableViewCellIdentifier forIndexPath:indexPath];

    if (_searchController.active && _searchController.searchBar.text.length > 0) {
        cell.textLabel.text = _searchResults[indexPath.row];
    }
    else {
        cell.textLabel.text = _dataSource[indexPath.row];
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (self.delegate && [self.delegate respondsToSelector:@selector(didSelectRowAtIndexPath:tableView:indexPath:)]) {
        [self.delegate didSelectRowAtIndexPath:self tableView:tableView indexPath:indexPath];
    }
}


- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
    [self filterResults:searchController.searchBar.text scope:nil];
}

- (void)filterResults:(NSString *)searchText scope:(NSString *)scope {
    _searchResults = [_dataSource filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id  _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {

        NSString *object = [evaluatedObject uppercaseString];
        return [object rangeOfString:[searchText uppercaseString]].location != NSNotFound;
    }]];

    [_tableView reloadData];
}

@end

然后我用下面的UIViewController 对其进行了测试,它嵌入在UINavigationController..

//
//  ViewController.m
//  StackOverflow
//
//  Created by Brandon T on 2016-06-26.
//  Copyright © 2016 XIO. All rights reserved.
//

#import "ViewController.h"
#import "SearchView.h"


@interface ViewController ()<SearchViewDelegate>
@property (nonatomic, strong) SearchView *searchView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self initControls];
    [self themeControls];
    [self doLayout];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}


- (void)initControls {
    _searchView = [[SearchView alloc] init];
}

- (void)themeControls {
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.navigationItem.titleView = [_searchView getSearchBar];

    [_searchView setDelegate:self];
}

- (void)doLayout {
    [self.view addSubview:_searchView];

    NSDictionary *views = @{@"searchView":_searchView};
    NSMutableArray *constraints = [[NSMutableArray alloc] init];

    [constraints addObject:[NSString stringWithFormat:@"H:|-%d-[searchView]-%d-|", 0, 0]];
    [constraints addObject:[NSString stringWithFormat:@"V:|-%d-[searchView]-%d-|", 0, 0]];

    for (NSString *constraint in constraints) {
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:constraint options:0 metrics:nil views:views]];
    }

    for (UIView *view in self.view.subviews) {
        [view setTranslatesAutoresizingMaskIntoConstraints:NO];
    }
}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
    self.navigationItem.leftBarButtonItems = nil;
    self.navigationItem.rightBarButtonItems = nil;
}

- (void)didSelectRowAtIndexPath:(SearchView *)searchView tableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath {

    [[searchView getWebView] stringByEvaluatingJavaScriptFromString:@"SomeJavascriptHere"];

}
@end

【讨论】:

  • 非常感谢人 - (UISearchBar *)getSearchBar { return _searchController.searchBar; } 这是我的代码中缺少的功能
  • 经过一些测试,当我点击搜索栏并输入 .它消失了
  • 我贴的代码没有隐藏搜索栏,因为:_searchController.hidesNavigationBarDuringPresentation = false; 并且搜索栏在导航栏中。
  • 是的,我也这样做了,当我输入搜索 imgur.com/dHSlE06 时我得到了这个
  • 其实是UITableView隐藏了导航栏
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-03
  • 1970-01-01
相关资源
最近更新 更多