I am new to IOS, I am trying to create an app where I need to display the webview of any site along with slide out menus . To achieve this I have tried using swrevealviewcontroller to get the slide out menu working and use the uiwebview on the controller page but now I need to pass url to webview from the slide out menu working with single uiwebview.
How can I achieve this , I have tried using this link
Pass a UIWebView request using prepareForSegue
but I am stuck at one point , I am getting error as
Urlstr does not belong to the class , I have checked it
it will be great if anyone could guide me with the complete step
Add an NSString property to the ViewController you are presenting like this:
#property (nonatomic, strong) NSString *webviewURLString;
Then when you present assign the ViewController's webviewURLString property with something like this:
MyViewController *myVC = [self.storyboard instantiateViewControllerWithIdentifier:#"myViewController"];
// THIS IS WHERE YOU ASSIGN IT
myVC.webviewURLString = #"<your url goes here>";
[self.navigationController pushViewController:myVC animated:YES];
Then when in MyViewController's viewDidLoad method you can check if webviewURLString has a value and if it does, start loading the web view with the url from webviewURLString.
Related
I am trying to implement a application which has five tabs totally. Each of tabs corresponds to a view controller, such as viewController1~viewController5.
For the viewController4, I add the navigationController on it in AppDelegate.m as following:
viewController4 = [[iPhone_ASRAViewController alloc] initWithNibName:#"iPhone_ASRAViewController_iPhone" bundle:nil];
navController1 = [[UINavigationController alloc]initWithRootViewController:viewController4];
In the iPhone_ASRViewController class, I have declared a property in .h file as following:
#property (nonatomic, retain) NSString *student_id;
Then, I want to access the student_id(set the student_id) which is declared in iPhone_ASRViewController in the FirstViewController, and implement in FirstViewController.m as following:
iPhone_ASRAViewController *iphone_ASRAVC= [self.tabBarController.viewControllers objectAtIndex:3];
iphone_ASRAVC.student_id=[stu_class stringByAppendingString:stu_id];
//stu_class and stu_id is the text field declared in the FirstViewController.
Ideally, when a certain button which is implemented in the FirstViewController class is pushed by users, the value of student_id will also be set to iPhone_ASRAViewController class.
Unfortunately, the app will crash when users push the button. Error msgs as following:
[UINavigationController setStudent_id:]: unrecognized selector sent to instance 0x9341170
Can someone provide me with some ideas/solutions to debug, please?
Well, wenn the view controllers in a tab bar have (or better are) navigation controllers, then the viewControllers array of the tab bar controller contains navigation controllers instead. Actually, you (or your storyboard) put them in!
It may well be a mix of view controllers and navigation controllers, depending of what was actually set upon creation or reconfiguration (if any) of the tab bar.
So I'd sugest to receive the object from viewContollers at the given index into something of type ID. Then check whether it is a navigation controller (use isKindOfClass:[iPhone_ASRAViewController class]) and if so then use it directly. If not then check whether it is of class UINavigationConroller (or the other way around - what ever is more convenient for you) and if so fetch its topViewController property and go from there.
Edit: Added in response to comments:
id someController = [self.tabBarController.viewControllers objectAtIndex:3];
if (someController isKindOfClass:[UINavigationController class]) {
someController = [someController topViewController]; //re-using someController
}
// someController should be a UIViewController from here onwards. But you may double check if you want.
if (someController isKindOfClass:[iPhone_ASRAViewController class]) {
iPhone_ASRAViewController *myIPhone_ASRAViewController (iPhone_ASRAViewController*) someController;
// you may now savely access those properties that are unique to your custom view controller class
}
I am trying to build a 2 scene application using Storyboards in iOS6.
I am taking the users name via text input in the first scene and passing it using a push segue to the second scene; where it is displayed in a label.
The first scene's UIViewController is called ViewController and the second scenes UIViewcontroller is DrawViewController.
I have imported the the DrawViewController.h in my ViewController.m file where I have defined the prepareForSegue as below:
-(void) prepareForSegue:(UIStoryboardSegue *) segue sender:(id) sender{
if ([segue.identifier isEqualToString:#"ColorPickerControllerSegue"]){
DrawViewController *dvc =[segue destinationViewController];
dvc.userName= self.userName;
}
}
Here userName is a NSString defined in DrawViewController.
I am getting "use of undeclared identifer:DrawViewController".
I am quite new to iOS programming, so is there something I am missing here?
I have set the second view controller's custom class to DrawViewController.
I was able to solve this issue by removing the existing DrawViewController.h and DrawViewController.m files and then creating and adding them back to the the project.
It seemed to do the trick.
I am creating some sample applications to understand the concepts of view navigation, binding etc in cocoa.
Here is the scenario:
I have a window that has a tab view(2 tabs) in MainMenu.Xib.
I have a text field in the first tab and label in the second tab. I want both of them to reflect the same value and I want to do this using binding. Also, I don't want to use the views provided to me along with the tab view.
These are the steps I have done.
The view of each tab view item is set separately in the applicationDidFinishLaunching: method using the following code:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
//initialize view controllers
view1=[[ViewTab1 alloc] initWithNibName:#"ViewTab1" bundle:nil];
view2=[[ViewTab2 alloc] initWithNibName:#"ViewTab2" bundle:nil];
//set views
[[[myTabView tabViewItems] objectAtIndex:0]setView:view1.view];
[[[myTabView tabViewItems] objectAtIndex:1]setView:view2.view];
}
myTabView is the outlet reference of the tab view from MainMenu.xib in AppDelegate.
ViewTab1 is the name of the first view controller (and the xib).
ViewTab2 is the name of the second view controller (and the xib).
ViewTab1 has one single text field (and an associated label). I have bound this to a variable(name) declared in AppDelegate.
ViewTab2 has a label. I have bound this also to the same variable in AppDelegate.
The variable, 'name' is initialized in the init method of AppDelegate.
AppDelegate.h
....
NSString *name;
....
#property(strong) ViewTab1 *view1;
#property(strong) ViewTab2 *view2;
#property (assign) IBOutlet NSTabView *myTabView;
#property (strong) NSString *name;
....
AppDelegate.m
....
#synthesize myTabView;
#synthesize view1,view2;
#synthesize name;
....
- (id)init {
self = [super init];
if (self) {
name=#"dummy";
}
return self;
....
Apart from this I haven't done any coding in my program.
In the ViewTab1.xib I got an object and made it an instance of AppDelegate and then connected the delegate reference of the Application object(NSApplication) to the same object. (I hope this is the right way of getting the AppDelegate object.)
I did the same in ViewTab2.xib
Then I bound the text field in ViewTab1 and label in ViewTab2 to this variable in AppDelegate.
When I run the program both the text field and label shows "dummy". But when I change the value in the text field, its not reflected in the label in the second tab( i.e. ViewTab2).
Please tell me what I'm doing wrong.
How to establish binding to the same App delegate object from any loaded Nib?
Yes, I know this frustrated situation as described in question... after many weeks and hundreds pages of documentation for KVO - Notifications - Bindings I think there is one very simple solution for that.
As we can find in some information sources the nib-loading process produce new instances of members... and we need to use binding connection to the old one.
Note that bindings made in InterfaceBuilder are redirect to these new instances automatically after loading nib
Why not redirect the pointer of App delegate to the old instance?
In method where you loads your nib you can test which object is app delegate before and just after nib load.
If the new one isn’t the same as the previous one you can redirect it as you want.
This simple example works for me in Xcode3 under 10.5.8 with target to OSX10.5 / i386:
// ***** SOMEWHERE IN DEFAULT APP-DELEGATE.m IMPLEMENTATION
- (IBAction) createOtherWindowFromNib: (id)sender
{
// ensure that app delegate is set as you want...
[NSApp setDelegate:self];
NSLog(#"APP-DELEGAT **** CREATE-TEST-WINDOW ***** WHO IS APP-DELEGATE BEFORE NIB LOAD: %# ", [[NSApp delegate] description]);
// we can bind members of the nib to this controller over proxy object named "File’s Owner"
NSWindowController *otherWinCapo = [[NSWindowController alloc] initWithWindowNibName: #"OtherTestWindow"];
NSLog(#"APP-DELEGAT **** CREATE-TEST-WINDOW ***** WHO IS APP-DELEGATE AFTER NIB LOAD: %# ", [[NSApp delegate] description]);
// make some test for delegates before/after here if you need ...
// usually your bindings made inside "OtherTestWindow.xib" by IB doesn’t works in this moment
// ... and some redirection if needed
[NSApp setDelegate:self];
// afer that the bind made in IB inside "OtherTestWindow.xib"
// referred to (proxy object) "Application.delegate.myBOOL" (Bind to:Application, Model Key Path:delegate.myBOOL)
// react to changes of myBOOL placed in default app delegate object as expected
// simultaneously in every open instance of "OtherTestWindow.xib"
[otherWinCapo showWindow: otherWinCapo.window]; // we need populate the window instance on screen to see it
}
I think the problem is that the objects in your xibs that you set to the app delegate class create 2 different instances of the app delegate, so changing the value of the text field changes the value of name in one instance but not in the other. That's what you're doing wrong, unfortunately, I can't think of a solution at this time.
Have you turned on 'Continuously Updates Value' in the NSTextField controls?
See this example.
I created a button in my cover.h file for my first view
#import <UIKit/UIKit.h>
#interface cover : UIViewController
{
IBOutlet UIButton *Enter;
}
#property (nonatomic, retain) UIButton *Enter;
-(IBAction)buttonpressed:(id)sender;
#end
and connected it with the actual button in the inteface builder by choosing File's Owner in the tiny box that gives you the choice of File's Owner, First Responder, and View
Then I went to cover.m file and added the following code
-(IBAction)buttonpressed:(id)sender
{
[[NSBundle mainBundle] loadNibNamed:#"nextView" owner:self options:nil];
NSLog(#"pressed");
}
SO when I go to the nextView.xib and modify nextView.m and nextView.h and access its buttons and do the same thing I did for cover.xib cover.m and cover.h , it doesn't work properly.
What happens is that when I click the enter button in the cover view it shuts down the app. This does not happen until I connected the button to function and outlet (Meaning when it was just switching views and the second view wasn't doing anything it would work)
Thank you for any help you can give. Sorry if I haven't given enough information, kinda new at this, but as find out more info I should have had, I will add it.
Thank you
Edit 1 :
I did not notice anywhere where it said there was an error or anything like that. It built correctly
It's convention to capitalize class names. I'd Suggest CoverViewController. This makes it more obvious, when reading your code, what we're looking at.
What is your intent here? To show nib after nib of content?
Is the "files owner" of every nib a CoverViewController?
What you have actually done is (catastrophically) reloaded the views for the existing controller. This will not end well.
What you want to do is create another instance of the same class:
-(IBAction)buttonpressed:(id)sender {
CoverViewController nextController = [[CoverViewController alloc] initWithNibName:#"nextView"];
[navigationController pushViewController:nextController animated:NO];
}
If you're not using a nav controller, you probably want to be.
Read up on the View Controller Programming Guide.
I have an app at the moment that when a button is pushed on the first screen does some work and makes a URL, and then does
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:currentURL]];
which launches Safari with my URL. I want instead to have a webview launch from here so the user can do some custom things with it. I am still having a hell of a time understanding MVC in iOS and need help. My project is minimal and consists of an AppDelegate.h/m and a ViewController.h/m, the.m of the view controller is where the function that does this Safari launch lives.
Can anyone help me understand how to do what I'm trying to d?
Thanks...
The simplest way is just to add a UIWebView when the button gets pressed. Add this method to your ViewController.m and have this be performed when the button gets pressed.
Programmatically:
//This method should get called when you want to add and load the web view
- (void)loadUIWebView
{
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; //Change self.view.bounds to a smaller CGRect if you don't want it to take up the whole screen
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:currentURL]]];
[self.view addSubview:webView];
[webView release];
}
Using Interface Builder:
1) Add a UIWebView object to your interface.
2) Set the "hidden" property to checked (in the "Attributes Inspector" window in Interface Builder). You'll keep it hidden until you want to show it.
3) Add the following code to your ViewController.h, below the other #property lines:
#property (nonatomic, retain) IBOutlet UIWebView *webView;
4) Add the following line below the #synthesize in your ViewController.m
#synthesize webView;
And add [webView release]; in the dealloc method.
5) Go back into IB and click on File's Owner, and connect the webView outlet to the webView you created.
6) Add the following method instead of the method I showed above (for the programmatic example):
//This method should get called when you want to add and load the web view
- (void)loadUIWebView
{
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:currentURL]]];
self.webView.hidden = NO;
}
You could set up an IBAction method to respond to the button press, but it sounds like you already have the button press working, so I wouldn't bother with that now.
As far as adding a button above the web view, you can either subclass web view and add the button there, or just have a separate button you define in your nib or programmatically and have that hide the webView to "get rid of it".
For adding UIWebView using Swift to your app just drag the WebView to your story board and then using an assistant editor connect WebView to ViewController.swift
And then Loading URL to WebView is very easy. Just create a WebView in your storyboard and then you can use the following code to load url.
let url = NSURL (string: "https://www.simplifiedios.net");
let request = NSURLRequest(URL: url!);
webView.loadRequest(request);
As simple as that only 3 lines of codes :)
Ref: UIWebView Example
Since this is the top result on Google, if you can use WKWebView instead of UIWebView, you should.
import WebKit
let webViewConfiguration = WKWebViewConfiguration()
let webView = WKWebView(frame: CGRect(), configuration: webViewConfiguration)