Reputation: 91
I have an app that reads an RSS feed and when a row in the table view is selected, it opens the article in a web view. I'm wanting a button to show an action sheet with an option to open the url in Safari. I'm using an action sheet because I'm going to add more buttons to it in the near future.
WebViewController.m
//
// WebViewController.m
// KFBNewsroom
//
// Created by KFB on 10/16/12.
// Copyright (c) 2012 com.kfb. All rights reserved.
//
#import "WebViewController.h"
@implementation WebViewController
- (void)loadView
{
// Create an instance of UIWebView as large as the screen
CGRect screenFrame = [[UIScreen mainScreen]applicationFrame];
UIWebView *wv = [[UIWebView alloc]initWithFrame:screenFrame];
// Tell web view to scale web content to fit within bounds of webview
[wv setScalesPageToFit:YES];
[self setView:wv];
}
- (UIWebView *)webView
{
return (UIWebView *)[self view];
}
@end
ListViewController.m
//
// ListViewController.m
// KFBNewsroom
//
// Created by KFB on 10/16/12.
// Copyright (c) 2012 com.kfb. All rights reserved.
//
#import "ListViewController.h"
#import "RSSChannel.h"
#import "RSSItem.h"
#import "WebViewController.h"
@implementation ListViewController
@synthesize webViewController;
- (void)viewDidLoad
{
self.title = @"Public Affairs";
UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
[refresh addTarget:self action:@selector(refreshView:)forControlEvents:UIControlEventValueChanged];
self.refreshControl = refresh;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(@"%@ found a %@ element", self, elementName);
if ([elementName isEqual:@"channel"])
{
// If the parser saw a channel, create new instance, store in our ivar
channel = [[RSSChannel alloc]init];
// Give the channel object a pointer back to ourselves for later
[channel setParentParserDelegate:self];
// Set the parser's delegate to the channel object
[parser setDelegate:channel];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// return 0;
NSLog(@"channel items %d", [[channel items]count]);
return [[channel items]count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// return nil;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"];
cell.textLabel.font=[UIFont systemFontOfSize:16.0];
}
RSSItem *item = [[channel items]objectAtIndex:[indexPath row]];
[[cell textLabel]setText:[item title]];
return cell;
}
- (void)fetchEntries
{
// Create a new data container for the stuff that comes back from the service
xmlData = [[NSMutableData alloc]init];
// Construct a URL that will ask the service for what you want -
NSURL *url = [NSURL URLWithString:@"http://kyfbnewsroom.com/category/public-affairs/feed"];
// Put that URL into an NSURLRequest
NSURLRequest *req = [NSURLRequest requestWithURL:url];
// Create a connection that will exchange this request for data from the URL
connection = [[NSURLConnection alloc]initWithRequest:req delegate:self startImmediately:YES];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self)
{
[self fetchEntries];
}
return self;
}
// This method will be called several times as the data arrives
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
// Add the incoming chunk of data to the container we are keeping
// The data always comes in the correct order
[xmlData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
/* We are just checking to make sure we are getting the XML
NSString *xmlCheck = [[NSString alloc]initWithData:xmlData encoding:NSUTF8StringEncoding];
NSLog(@"xmlCheck = %@", xmlCheck);*/
// Create the parser object with the data received from the web service
NSXMLParser *parser = [[NSXMLParser alloc]initWithData:xmlData];
// Give it a delegate
[parser setDelegate:self];
//Tell it to start parsing - the document will be parsed and the delegate of NSXMLParser will get all of its delegate messages sent to it before this line finishes execution - it is blocking
[parser parse];
// Get rid of the XML data as we no longer need it
xmlData = nil;
// Reload the table.. for now, the table will be empty
[[self tableView]reloadData];
NSLog(@"%@\n %@\n %@\n", channel, [channel title], [channel infoString]);
}
- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
{
// Release the connection object, we're done with it
connection = nil;
// Release the xmlData object, we're done with it
xmlData = nil;
// Grab the description of the error object passed to us
NSString *errorString = [NSString stringWithFormat:@"Fetch failed: %@", [error localizedDescription]];
// Create and show an alert view with this error displayed
UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[av show];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Push the web view controller onto the navigation stack - this implicitly creates the web view controller's view the first time through
// [[self navigationController]pushViewController:webViewController animated:YES];
[self.navigationController pushViewController:webViewController animated:YES];
// Grab the selected item
RSSItem *entry = [[channel items]objectAtIndex:[indexPath row]];
NSLog(@"Channel Items: %@", [[channel items]objectAtIndex:[indexPath row]]);
// Construct a URL with the link string of the item
NSURL *url = [NSURL URLWithString:[entry link]];
NSLog(@"Link: %@", [entry link]);
// Construct a request object with that URL
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSLog(@"URL: %@", url);
// Load the request into the web view
[[webViewController webView]loadRequest:req];
NSLog(@"Request: %@", req);
// Set the title of the web view controller's navigation item
[[webViewController navigationItem]setTitle:[entry title]];
NSLog(@"Title: %@", [entry title]);
}
-(void)refreshView:(UIRefreshControl *)refresh
{
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refreshing data..."];
// custom refresh logic would be placed here...
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"MMM d, h:mm a"];
NSString *lastUpdated = [NSString stringWithFormat:@"Last updated on %@",[formatter stringFromDate:[NSDate date]]];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdated];
[refresh endRefreshing];
}
@end
Here is how I'm doing it in another view but it is much easier because it is only using one specific URL.
//
// KYFB.m
// KFBNewsroom
//
// Created by KFB on 11/14/12.
// Copyright (c) 2012 com.kfb. All rights reserved.
//
#import "KYFB.h"
#import <MessageUI/MessageUI.h>
@interface KYFB ()
@end
@implementation KYFB
@synthesize webView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(@"KYFB.com", @"KYFB.com");
self.tabBarItem.image = [UIImage imageNamed:@"kyfb-com"];
}
return self;
}
- (void) showMenu
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"" delegate:self cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil otherButtonTitles: @"Open in Safari", nil, nil];
actionSheet.actionSheetStyle = self.navigationController.navigationBar.barStyle;
[actionSheet showInView:self.parentViewController.tabBarController.view];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSString *urlAddress = @"http:www.kyfb.com";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
UIBarButtonItem *systemAction = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(showMenu)];
self.navigationItem.rightBarButtonItem = systemAction;
}
- (void)actionSheet:(UIActionSheet *)modalView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSURL *url = [NSURL URLWithString:@"http://www.kyfb.com"];
switch (buttonIndex)
{
case 0:
{
[[UIApplication sharedApplication] openURL:url];
break;
}
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
I'm just not sure how to implement this idea for WebViewController and ListViewController.
UPDATE: I've added code to my WebViewController class. The system action button now appears on the web view navigation bar and when pressed it pulls up the action sheet but the open in safari button doesn't do anything.
WebViewController.h
//
// WebViewController.h
// KFBNewsroom
//
// Created by KFB on 10/16/12.
// Copyright (c) 2012 com.kfb. All rights reserved.
//
#import <Foundation/Foundation.h>
// @interface WebViewController : NSObject
@interface WebViewController : UIViewController <UIActionSheetDelegate>
{
IBOutlet UIWebView *webView;
}
@property (nonatomic, readonly)UIWebView *webView;
@end
WebViewController.m
//
// WebViewController.m
// KFBNewsroom
//
// Created by KFB on 10/16/12.
// Copyright (c) 2012 com.kfb. All rights reserved.
//
#import "WebViewController.h"
@implementation WebViewController
@synthesize webView;
- (void)loadView
{
// Create an instance of UIWebView as large as the screen
CGRect screenFrame = [[UIScreen mainScreen]applicationFrame];
UIWebView *wv = [[UIWebView alloc]initWithFrame:screenFrame];
// Tell web view to scale web content to fit within bounds of webview
[wv setScalesPageToFit:YES];
[self setView:wv];
}
- (UIWebView *)webView
{
return (UIWebView *)[self view];
}
- (void) showMenu
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"" delegate:self cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil otherButtonTitles: @"Open in Safari", nil, nil];
actionSheet.actionSheetStyle = self.navigationController.navigationBar.barStyle;
[actionSheet showInView:self.parentViewController.tabBarController.view];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
UIBarButtonItem *systemAction = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(showMenu)];
self.navigationItem.rightBarButtonItem = systemAction;
}
- (void)actionSheet:(UIActionSheet *)modalView clickedButtonAtIndex:(NSInteger)buttonIndex
{
// NSURL *url = [NSURL URLWithString:@"http://www.kyfb.com"];
NSURL *url= webView.request.URL;
switch (buttonIndex)
{
case 0:
{
[[UIApplication sharedApplication] openURL:url];
break;
}
}
}
@end
Upvotes: 0
Views: 805
Reputation: 7633
In the clickedButtonAtIndex:
you can use the current URL of your webview:
NSURL *url= webView.request.URL;
//or NSURL *url = [NSURL URLWithString:webView.request.URL.absoluteString];
Upvotes: 1