Link Navigation View Controller cell to a Web View - iphone

I have a navigation controller with multiple cells. I want to link each of the cells to a webpage in a web view. However, I don't want to create another view controller for each cell. Is it possible to create 1 view controller and link all cells to the same view controller but make a different webpage show up in the web view for each cell? For example, there is cell 1 and cell 2. They both link to one view controller with a web view in the view controller. When you click cell 1, it brings you to the view controller and in the web view it brings you to http://example.com. When you click cell 2, it brings you to the same view controller as cell 1 but in the web view, it brings you to http://example.com/1. How can I do that?

Just declare a property in your viewcontroller which holds the URL you want to request.
#property (strong,nonatomic) NSString *url;
When you click on a cell assign the URL of the cell accordingly to the property of your viewcontroller
Your viewcontroller should look something like this.
Header
#import <UIKit/UIKit.h>
#interface RSViewController : UIViewController
#property (weak, nonatomic) NSString *url;
#end
Implementation
#import "RSViewController.h"
#interface RSViewController ()<UIWebViewDelegate>
#property (strong,nonatomic) IBOutlet UIWebView *webview;
#end
#implementation RSViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.webview.delegate = self;
NSURLRequest *urlRequest = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:self.url]];
[self.webview loadRequest:urlRequest];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)webViewDidStartLoad:(UIWebView *)webView
{
NSLog(#"Did start loading");
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(#"Did finish loading");
}
#end
Now you just need a reference to your viewcontroller in your tableviewcontrollerand set the urlproperty on cell click.

Related

UIScrollView with IUViewController dropping objects

I have a really weird issue with UIScrollView and added UIViewControllers.
It looks like that when UIViewControllers are added to UIScrollView for paging, the UIViewController drops all its added objects.
In the project i have a storyboard with two views and they are connected correctly to the corresponding code.
I know that the code doesn't move the added UIViewController to the correct X, but in this test im only adding one UIViewController so it doesnt matter.
This is the scroll code .h:
#import <UIKit/UIKit.h>
#import "TestViewController.h"
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
#property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
#property (strong, nonatomic) NSMutableArray *scrollController;
#end
This is the scroll code .m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.scrollController = [[NSMutableArray alloc] init];
}
- (void)viewDidAppear:(BOOL)animated {
//just adding two controllers
TestViewController *first = [[TestViewController alloc] init];
[self.scrollView addSubview:first.view];
[self.scrollController addObject:first];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * self.scrollController.count, self.scrollView.frame.size.height);
self.pageControl.numberOfPages = [self.scrollController count];
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
// Update the page when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
This is the viewcontroller code .h:
#import <UIKit/UIKit.h>
#interface TestViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *lblMsg;
#end
This is the viewcontroller code .m:
#import "TestViewController.h"
#interface TestViewController ()
#end
#implementation TestViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(#"Label: %#", self.lblMsg);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The output in log is:
Label: (null)
Anybody able to see what im doing wrong?
If you create your ViewController using
TestViewController *first = [[TestViewController alloc] init];
your label (IBOutlet) won't be linked.
Navigate to your storyboard in Xcode, select your viewcontroller and assign a unique storyboard id ("myIdentifier") in the identity inspector in utilities on the right hand side.
Try
NSString *identifier = #"myIdentifier";
TestViewController *first = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
Have a look at the documentation:
Each view controller object is the sole owner of its view. You must
not associate the same view object with multiple view controller
objects. The only exception to this rule is that a container view
controller implementation may add this view as a subview in its own
view hierarchy. Before adding the subview, the container must first
call its addChildViewController: method to create a parent-child
relationship between the two view controller objects.

How to send data from UItextfields of one viewcontroller to new view controller? [duplicate]

I am a bit stuck on trying to pass data from two UITextfields on one viewcontroller to another viewcontroller. Basically I got the items below:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
IBOutlet UITextfield *Textfield1;
IBOutlet UITextfield *Textfield2;
}
-(IBAction)GoNextView:(id)sender;
#end
ViewController.m
#interface ViewController ()
#end
#implementation ViewController
(IBAction)GoNextView:(id)sender {
SecondView *second = [[SecondView alloc] initWithNibName:nil bundle:nil];
[self presentViewController:second animated:YES completion:NULL];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
SecondView.h
#import <UIKit/UIKit.h>
#interface SecondView : UIViewController {
IBOutlet UILabel *ShowTextfield1;
IBOutlet UILabel *ShowTextfield2;
}
-(IBAction)GoBack:(id)sender;
#end
SecondView.m
#interface SecondView ()
#end
#implementation SecondView
- (IBAction)GoBack:(id)sender {
[self dismissViewControllerAnimated:YES completion:NULL];
}
What I want is, that when the button GoNextView is pressed it should pass the data in the UITextfield to the SecondView. And the go to the next page. The data should now be displayed in the two Labels on the SecondView. I've been struggling with this for many hours now and its killing me. I know I have to use some NSString and #property(nonatomic, retain) NSString *asdas. But I simply can't make it work. So based on the above code how do I pass data from the two UITextfield to the two labels on the next view?
Instead of navigating to the second view through a function, use Storyboard Segues. Create a storybaord application. To Create a segue you need a navigation view controller. You can do that by the following steps.
Select the first view controller and go to Editor -> Embed In -> Navigation Controller.
Then Ctrl+Click on the "GoNextView" button, and drag and drop in the SecondView.
You will get three options: push, model, custom. Click push then a segue will be created between these two views.
Click that segue and click the "Show the Attribute Inspector" on the right side property window. Now name it as "connector" or which ever name you prefer.
Now, in SecondView.h create two strings,
#property (nonatomic, retain) NSString *str1;
#property (nonatomic, retain) NSString *str2;
and synthesize them in SecondView.m.
Lets name your UITextFields as "text1" and "text2" which are in your ViewController. Go to the ViewController.h and add #import "SecondView.h"
In ViewController.m do the following,
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"connector"])
{
ViewController *VC = [segue destinationViewController];
VC.str1 = text1.text;
VC.str2 = text2.text;
}
}
Now you can display these strings in your SecondView. In Secondview.m,
label.text = str1;
and it will be displayed.
Use NSUserDefaults or the normal synthesising common interface variables. For example,
NSUserDefaults
From sender's view controller,
NSString *text=textField1.text;
NSUserDefaults *prefs=[NSUserDefaults standardUserDefaults];
[prefs setObject:text forKey:#"text1value"];
And you can get the value from any view controller as,
NSUserDefaults *prefs=[NSUserDefaults standardUserDefaults];
NSString *received string= [prefs stringForKey:#"text1value"];
Normal assigners,
I believe you must be using performsegue to navigate view controllers. There is a delegate method called "prepareforsegue" and you can assign the textfield values into the interface variables. For example,
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"seguename"]) {
destViewController *destViewController = segue.destinationViewController;
destViewController.name = #"some text";
}
}
In the receiver's view controller, getter variable is actually defined as,
In .h file, #property(nonatomic, strong) NSString *name;
In .m file, Don't forget to synthesis the variable after implementation
#implementation destViewController
#synthesize name;
Hope it helps!

How to justify text in a textbox ios?

I am developing an app for the iphone. One of my views contains a textbox that I used to display text. I used storyboard to do this. To better explain, this view will show the user the history of a football team. E.g " the team was established in 1990" etc and give a full history of the team. So there will be no user interaction. The reader will only read the text and move on to the next page. Is using a textbox for the text a good idea? And is there anyway to justify the alignment of the text so the ends of the lines are all alligned?
I think You will Use WebView Because justified aligment for text you only have center, left and right by UItextView.
IF You Want to Use UiWebView then set in
className.h
#interface className : UIViewController {
IBOutlet UIWebView *webviewName;
}
#property (nonatomic, retain) UIWebView *webviewName;
className.m
[webviewName loadHTMLString:[NSString stringWithFormat:#"<div align='justify'>%#<div>",TEXT_set] baseURL:nil];
UITextView is a good way to go, but it has no option to justify the text it contains. Another approach is using a UIWebView to display a simple HTML document.
To have nice looking justified text in HTML set the text-align property to justify and may use some JavaScript to enhance line-breaking.
Hope that helps :)
ok there is no problem with that u shoud to use textView ,just make sure its user intteraction is disable, while if ur data is coming dynamic than u should to use Web view, this make alignment correct
I have found that a generic view controller subclass to load a web view is very reusable. I have two. One designed for a navigation controller, and another designed a a modal view controller. I use them over and again with modification for things like help, legal information, and about my company. It would work very well for your purposes.
I use KempoZer as my free html editor to create the files I load in it. The advantage is that the html editor allows me to add bold, italic, headings, and different font sizes.
In storyboard I have several segues to the same view controller and set the two properties in a prepare for segue method in the view controller that calls the html view controller.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"instructions"]) {
[[segue destinationViewController] setNavigationTitle:#"Instructions"];
[[segue destinationViewController] setHtmlFileName:#""];
} else if ([[segue identifier] isEqualToString:#"legal"]) {
[[segue destinationViewController] setNavigationTitle:#"Legal Notices"];
[[segue destinationViewController] setHtmlFileName:#"legal.html"];
} else if ([[segue identifier] isEqualToString:#"about"]) {
[[segue destinationViewController] setNavigationTitle:#"About"];
[[segue destinationViewController] setHtmlFileName:#"AboutSuperDuperCoolApps.html"];
} else if ([[segue identifier] isEqualToString:#"videoTutorials"]) {
[[segue destinationViewController] setNavigationTitle:#"Video Tutorials"];
[[segue destinationViewController] setHtmlFileName:#""];
}
}
Here is the nab controller version, don't forget to create the storyboard view controller and hook up the web view.
// HTMLViewController.h
#import <UIKit/UIKit.h>
#interface HTMLViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIWebView *webView;
#property (strong, nonatomic) NSString *htmlFileName;
#property (strong, nonatomic) NSString *navigationTitle;
#end
and
// HTMLViewController.
#import "HTMLViewController.h"
#implementation HTMLViewController
#synthesize webView, htmlFileName, navigationTitle;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
//
[self.navigationItem setTitle:navigationTitle];
// load selected html file
NSString *bundle = [[NSBundle mainBundle] bundlePath];
NSString *webPath = [bundle stringByAppendingPathComponent:htmlFileName];
[super viewDidLoad];
[webView loadRequest:[NSURLRequest requestWithURL:
[NSURL fileURLWithPath:webPath]]];
//
[super viewDidLoad];
}
- (void)viewDidUnload
{
[self setWebView:nil];
[self setHtmlFileName:nil];
[self setNavigationTitle:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end

Connecting To a Label Within A UIView Of A Tab

I am creating my first tab controller app. I have 2 tabs with 2 UIViews in them. I did this mostly from Interface Builder all I did in Xcode was add 2 files firstControllerView and SecController view. I can see the tab controller is working went I run the app (I simply changed the background color on the 2 UIViews in the tabs to see the effect).
Now I want to add a label to the secondView and set its text programmatically from code. This is whats breaking for me! I am doing something wrong. In my SecondViewController.h it looks like this:
#interface SecondViewController : UIViewController {
IBOutlet UILabel *title;
}
#property (nonatomic,retain) UILabel *title;
#end
and the .m looks like this...
#import "SecondViewController.h"
#implementation SecondViewController
#synthesize title;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[title setText:#"Hello Nick"];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[title release];
[super dealloc];
}
#end
After this I went back to Interface Builder and dragged the outlet reference to the label. When I run the simulator it crashes.
What am I missing here? It must be something simple.
Forgot to create an outlet for a tabbarcontroller in the app delegate then connect that outlet to the tabbar controller in interface builder.

iPhone - creating a loading view

When the app is in one view controller, I want to add a view to simulate that data is being loaded when I click my tab bar controller to open another view controller.
Example: When I the app is in the recorder-view, I want it to show a loading view (a view with a activity indicator) when I change to the list of recorded files (which can take some time to load). I've tried manipulate this with the viewWillDisappear-event, but I can't get it to work - the view is not being added before after the viewDidAppear-event occurs.
Anyone have any thoughts regarding this?
Thanks
Thank you for your reply. I tried doing like tou suggested, but I still can't get it to show when I want. I try to set hidden = NO in my viewWillDisappear-event, but it does not show before that view controller disappears and the next one appears
Right now it sounds like you have a UITabBarController That takes up the whole screen. What I would do is put the loading view above the TabBarController and hide it when not necessary. I would create a subclass of loadingViewController in the same xib your tab bar controller came from (or programatically if you desire) and set it to an IBOutlet of the App Delegate.
Something like this:
//In your App Delegate
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:tabBarController.view];
loadingView.hidden = YES;
[window insertSubview:loadingViewController.view aboveSubview:abBarController.view];
[window makeKeyAndVisible];
}
//In your loading View Controller
- (void) setLoadingViewHidden:(BOOL)hidden {
self.view.hidden = hidden;
self.activityIndicator.animating = hidden;
}
The way I've done this in the past is to have a content view which houses either an activity view or the view proper.
In the view controller's nib, instead of adding subviews to the main view, leave it empty and create a new view (such as a table view in the example below) for the view proper.
Also create an activity view (with a threaded progress indicator or somesuch) and a "no results" view.
Then derive your controller class from the something like the following:
//
// ContainerViewController.h
//
#import <UIKit/UIKit.h>
#interface ContainerViewController : UIViewController
{
UIView *myContainerView;
UITableView *myTableView;
UIView *mySearchActivityView;
UIView *myZeroResultsView;
UIView *myCurrentlyShowingView;
}
#property (retain, nonatomic) IBOutlet UIView *containerView;
#property (retain, nonatomic) IBOutlet UITableView *tableView;
#property (retain, nonatomic) IBOutlet UIView *searchActivityView;
#property (retain, nonatomic) IBOutlet UIView *zeroResultsView;
#property (assign) UIView *currentlyShowingView;
#end
//
// ContainerViewController.m
//
#import "ContainerViewController.h"
#implementation ContainerViewController
#synthesize containerView = myContainerView;
#synthesize tableView = myTableView;
#synthesize searchActivityView = mySearchActivityView;
#synthesize zeroResultsView = myZeroResultsView;
- (void)dealloc
{
[myContainerView release], myContainerView = nil;
[myTableView release], myTableView = nil;
[mySearchActivityView release], mySearchActivityView = nil;
[myZeroResultsView release], myZeroResultsView = nil;
myCurrentlyShowingView = nil;
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.currentlyShowingView = mySearchActivityView;
mySearchActivityView.backgroundColor = [UIColor clearColor];
myZeroResultsView.backgroundColor = [UIColor clearColor];
}
- (void)setCurrentlyShowingView:(UIView *)view
{
[myCurrentlyShowingView removeFromSuperview];
CGRect frame = view.frame;
frame.size = myContainerView.frame.size;
view.frame = frame;
[myContainerView addSubview:view];
myCurrentlyShowingView = view;
if (view == myTableView)
[myTableView reloadData];
}
- (UIView *)currentlyShowingView
{
return myCurrentlyShowingView;
}
#end
And in the -viewDidLoad method of the derived class, set off the (asynchronous) query:
- (void)viewDidLoad
{
[super viewDidLoad];
myQueryLoader = [[QueryLoader alloc] initWithQuery:#"whatever" delegate:self];
self.currentlyShowingView = mySearchActivityView;
}
and in the delegate callback:
- (void)queryLoader:(QueryLoader *)queryLoader didEndWithResults:(id)results error:(NSError *)error
{
myItems = [results retain];
if (myItems)
self.currentlyShowingView = myTableView;
else
self.currentlyShowingView = myZeroResultsView;
}
Hope this helps!