点击一个textView里的link导航至程序内可返回的自定义webView

本文介绍了一种在iOS应用中自定义处理URL的方法,并详细展示了如何通过代理模式使用UIWebView来加载网页,同时实现了WebView与AppDelegate间的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1,在AppDelegate.h里定义一个 

id currentViewController;

在AppDelegate.m里

@implementation UIApplication (Private)


- (BOOL)customOpenURL:(NSURL*)url

{

    beautyAppDelegate *MyWatcher = [[UIApplication sharedApplication] delegate];

    if (MyWatcher.currentViewController) {

        [MyWatcher.currentViewController handleURL:url];

        return YES;

    }

    return NO;

}


@end

- (void)applicationDidBecomeActive:(UIApplication *)application {  

    Method customOpenUrl = class_getInstanceMethod([UIApplication class], @selector(customOpenURL:));

    Method openUrl = class_getInstanceMethod([UIApplication class], @selector(openURL:));

    

    method_exchangeImplementations(openUrl, customOpenUrl);

}


在某个viewController里 AppDelegate.currentViewController = self;

viewController里定义一个 -(void)handleURL:(NSURL*)url,在这个函数里加载一个自定义的webView;

当viewController里有某个链接url用户点击时就会回调AppDelegate的- (BOOL)customOpenURL:(NSURL*)url;


自定义的webView代码如下:

WebViewController.h里

#import <UIKit/UIKit.h>


@interface WebViewController : UIViewController <UIActionSheetDelegate, UIWebViewDelegate> {

  UIWebView *webView;

  NSURL *url;


  UIToolbar* toolbar;


  UIBarButtonItem *backButton;

  UIBarButtonItem *forwardButton;

  UIBarButtonItem *actionButton;

}


@property (nonatomic, retain) UIWebView *webView;

@property (nonatomic, retain) NSURL *url;


@property (nonatomic, retain) UIToolbar* toolbar;

@property (nonatomic, retain) UIBarButtonItem *backButton;

@property (nonatomic, retain) UIBarButtonItem *forwardButton;

@property (nonatomic, retain) UIBarButtonItem *actionButton;


- (id) initWithURL:(NSURL*)u;

- (void) doAction;


- (void)goBack;

- (void)goForward;


- (void)reload;

- (void)stop;


@end


WebViewController.m里:


#import <objc/runtime.h>

#import "beautyAppDelegate.h"

#import "WebViewController.h"


typedef enum {

BUTTON_RELOAD,

BUTTON_STOP,

} ToolbarButton;


@interface WebViewController (Private)

- (void)updateToolbar:(ToolbarButton)state;

@end;


@implementation WebViewController


@synthesize webView;

@synthesize url;


@synthesize toolbar, backButton, forwardButton, actionButton;


- (id) initWithURL:(NSURL *)u

{

  if ( (self = [super init]) )

  {

    backButton    = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back.png"] style:UIBarButtonItemStylePlain target:self action:@selector(goBack)];

    forwardButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"forward.png"] style:UIBarButtonItemStylePlain target:self action:@selector(goForward)];

    actionButton  = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(doAction)];


    toolbar           = [UIToolbar new];

    toolbar.barStyle  = UIBarStyleDefault;

    toolbar.tintColor = [UIColor lightGrayColor];

    

    [toolbar sizeToFit];

    CGFloat toolbarHeight = [toolbar frame].size.height;

    CGRect mainViewBounds = self.view.bounds;

    [toolbar setFrame:CGRectMake(CGRectGetMinX(mainViewBounds),

                                 CGRectGetMinY(mainViewBounds) + CGRectGetHeight(mainViewBounds) - (toolbarHeight * 2.0) + 2.0,

                                 CGRectGetWidth(mainViewBounds),

                                 toolbarHeight)];


    webView                 = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 380)];

    webView.delegate        = self;

    webView.scalesPageToFit = YES;


    url = [u copy];

    

    [self.view addSubview:webView];

    [self.view addSubview:toolbar];


    UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

    

    NSArray *items = [NSArray arrayWithObjects: flexItem, backButton, flexItem, flexItem, flexItem, forwardButton

                                                flexItem, flexItem, flexItem, flexItem, flexItem, flexItem,

                                                actionButton, flexItem, flexItem, flexItem, actionButton, flexItem, nil];

    [self.toolbar setItems:items animated:NO];

    

    [webView loadRequest:[NSURLRequest requestWithURL:url]];

    

  }

  return self;

}


- (void)viewDidAppear:(BOOL)animated

{

  [super viewDidAppear:animated];

}


- (void)viewWillDisappear:(BOOL)animated

{

  [webView stopLoading];

  [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

}


#pragma mark -

#pragma mark WebViewActions


- (void)reload

{

  [webView reload];

  [self updateToolbar:BUTTON_STOP];

}


- (void)stop

{

  [webView stopLoading];

  [self updateToolbar:BUTTON_RELOAD];

}


- (void) goBack

{

  [webView goBack];

}


- (void) goForward

{

  [webView goForward];

}


- (void) doAction

{

  UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:[self.url absoluteString]

                                                           delegate:self

                                                  cancelButtonTitle:@"Cancel"

                                             destructiveButtonTitle:nil

                                                  otherButtonTitles:@"Open with Safari", nil];


  [actionSheet showInView:self.navigationController.view];

  [actionSheet release];

}


- (void)actionSheet:(UIActionSheet *)as clickedButtonAtIndex:(NSInteger)buttonIndex

{

  if (as.cancelButtonIndex == buttonIndex) return;


  if (buttonIndex == 0) {    

    // swizzle methods, from here we want to open Safari

    

    Method customOpenUrl = class_getInstanceMethod([UIApplication class], @selector(customOpenURL:));

    Method openUrl = class_getInstanceMethod([UIApplication class], @selector(openURL:));


    method_exchangeImplementations(customOpenUrl, openUrl);

    

    [[UIApplication sharedApplication] openURL:self.url];

  }

}


#pragma mark -

#pragma mark UIWebView


- (BOOL)webView:(UIWebView *)aWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

{

  return true;

}


- (void)webViewDidStartLoad:(UIWebView *)aWebView

{

  [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

  [self updateToolbar:BUTTON_STOP];

}


- (void)webViewDidFinishLoad:(UIWebView *)aWebView

{

  [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

  self.title = [aWebView stringByEvaluatingJavaScriptFromString:@"document.title"];

  [self updateToolbar:BUTTON_RELOAD];

  self.url = aWebView.request.mainDocumentURL;

}


- (void)webView:(UIWebView *)aWebView didFailLoadWithError:(NSError *)error

{

  [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

}


-(void)updateToolbar:(ToolbarButton)button

{

  NSMutableArray *items = [toolbar.items mutableCopy];

  UIBarButtonItem *newItem;


  if (button == BUTTON_STOP) {

    UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];

    [activityView startAnimating];

    newItem = [[UIBarButtonItem alloc] initWithCustomView:activityView];

    [activityView release];

  }

  else {

    newItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(reload)] autorelease];

  }


  [items replaceObjectAtIndex:12 withObject:newItem];

  [toolbar setItems:items animated:false];

  [items release];


  // workaround to change toolbar state

  backButton.enabled = true;

  forwardButton.enabled = true;

  backButton.enabled = false;

  forwardButton.enabled = false;


  backButton.enabled = (webView.canGoBack) ? true : false;

  forwardButton.enabled = (webView.canGoForward) ? true : false;

}


#pragma mark -


- (void)dealloc

{

  [webView release];

  [url release];

  [toolbar release];


  [backButton release];

  [forwardButton release];

  [actionButton release];


  [super dealloc];

}


@end



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值