ViewController and drawRect - iphone

I have a UIViewController and I would like it to call drawRect so i can draw on the view but nothing happens.
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
...code...
}
#end
and the implementation
#import "ViewController.h"
#implementation ViewController
-(void) drawRect:(CGRect) rect {
draw a pony
}
- (void)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 {
[super dealloc];
}
#end
But no pony gets drawn on the view when the app is run, what do i do wrong?

The UIViewController don't have overridden message drawRect.
You should create custom class derived from UIView and override message drawRect there.
You can override message (UIView *)view for UIViewController and return own custom UIView or in Interface Builder change class from UIView to own class.

Calling setNeedsDisplay on your UIView, not the ViewController, is one way of triggering and re-triggering your drawRect code, and you can send this message conditionally whenever you need to update the entire view.
You can call it within a custom UIView using
[self.setNeedsDisplay]
or from the View Controller by making the UIView a property of the controller and calling
[self.myView setNeedsDisplay]

Related

how to change WebView with buttons in separate View Controller

I need to change the URL of a WebView (located in WebViewViewController) using buttons in View Controller 1 (called PracticeViewController). I totally understand how to change the web View when it is in the same View Controller as the buttons, but I don't understand how to get the buttons to affect the WebView when the WebView is in a different ViewController than the buttons. Below is the code I currently have:
PracticeViewController.h
#import <UIKit/UIKit.h>
#interface PracticeViewController : UIViewController
- (IBAction)passGoogleButton:(id)sender;
- (IBAction)passYahooButton:(id)sender;
- (IBAction)passBingButton:(id)sender;
/* ok I tried to make this as clear as possible, and you can look at the other files if you don't understand what I mean, but at its core I want to change the web site loaded by the Web View by clicking on the buttons in the other View Controller */
#end
space (BTW is there an easier way to post on StackOverFlow Besides pressing space 4 times for every line of code? am I missing something?)
PracticeViewController.m
#import "PracticeViewController.h"
#import "WebViewViewController.h"
#interface PracticeViewController ()
#end
#implementation PracticeViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)passGoogleButton:(id)sender {
WebViewViewController.webSiteURL = #"http://www.google.com";
/* This supposedly works on a tutorial I saw, but Xcode flags it with the error 'Property webSiteURL not found on object of type 'WebViewViewController'' */
}
- (IBAction)passYahooButton:(id)sender {
WebViewViewController.webSiteURL = #"http://www.yahoo.com";
//same error as above
}
- (IBAction)passBingButton:(id)sender {
WebViewViewController.webSiteURL = #"http://www.bing.com";
//same error as above
}
#end
space
WebViewViewController.h
#import <UIKit/UIKit.h>
#interface WebViewViewController : UIViewController
{
UIWebView *myWebView;
NSString *webSiteURL;
}
#property (weak, nonatomic) IBOutlet UIWebView *myWebView;
#property (strong, nonatomic) NSString *webSiteURL;
/* I don't entirely understand what 'strong' means but I know it has to do with memory retention and that it (supposedly) should be used when I wan to transfer the value of the string 'webSiteURL' to the other ViewController */
#end
space
WebViewViewController.m
#import "WebViewViewController.h"
#interface WebViewViewController ()
#end
#implementation WebViewViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:webSiteURL]]];
/* As you can see above, the WebView loads from the string 'webSiteURL' but I can't figure out how to assign different values to it based on what button is clicked in the other View Controller so that it will run in ' - (void)viewDidLoad.' I already know how to transfer the value of the string to other things within another view controller (like into a label or a text field) but what I really need to know is how to get the string 'webSiteURL' to change before the view is loaded */
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You have the right idea but you are missing a step here. You are never creating an instance of webViewController.
What you need somewhere is...
webViewcontroller *MyWebController = [[webViewController alloc] init];
It depends on how you are presenting the WebViewController. If you simply want the button to pop up the WebViewController modally you could use the following:
- (IBAction)passGoogleButton:(id)sender {
webViewController *myWebVC = [[webViewController alloc] init];
[myWebVC setWebSiteURL:#"http://www.google.com"];
[self presentViewController:myWebVC animated:YES completion:nil];
}
So, you can see here. You create the instance of the webViewController called myWebVC. Then you pass the string to it. So when myWebVC loads and it hits viewDidLoad, it will use the string that you passed in already and load the web view with that content. Hope that helps.
Also, Make sure you #synthesize your properties in your .m files.
You can use nsnotificationcenter to accomplish this task.
First register to notificationcenter in WebViewController, then send notification from another controller.
Here's a sample for registering to notificationcenter in WebViewController
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(nMessageOpenURL:) name:#"nMessageOpenURL" object:nil];
This is the code to run the logic when you receive the notification. (in WebViewController)
- (void)nMessageOpenURL:(NSNotification *)note {
//run the logic in here.
}
And finally this is the code where you trigger the notification.
[[NSNotificationCenter defaultCenter] postNotificationName:#"nMessageOpenURL" object:nil];
Here's the Apple documentation.
I got to know that you are trying to pass the value of the string of url between two view controllers but you are not getting it right!!
So if you are using storyboard you can try out passing this value using Segue. For Eg: you can use prepareForSegue to set the different values using if-else construct.
And if you are not using segue the best practice to pass those values will be using delegate.
Just create a delegate method and pass the url string as an argument.
Hope this works :)

shouldStartLoadwithRequest not getting called in subclass

I have a view controlled app. On my xib I have no webviews but I do have buttons that bring up classes that have webviews. So hit button one and a uiwebview pops up so on and so forth.
Now in one of my classes I pull up a remote webpage that has a link on it. I want to over-ride that button link with shouldStartLoadwithrequest. How ever this never seems to get called.
Right now my class is called Tenth.m and I have this code in my view controller
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#" Test spot 1");
NSString* scheme = [[request URL] scheme];
if ([#"didTap" isEqual:scheme]) {
// Call your method
NSLog(#" Test spot 2");
[self didTapButton1];
return NO;
} else {
NSLog(#" Test spot 3");
return YES;
}}
But I get nothing (none of my NSLogs). I have tried putting this into my Tenth.m class and still nothing. I have looked at other examples and even downloaded one but it only uses the viewcontroller and delegates classes. No third class.
I'm lost as to why its not getting called.
Here is my third class
#import "Tenth.h"
#implementation Tenth
- (void)awakeFromNib
{
[category10 loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.mywebsite.com/api/didtap.php"]]];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (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 loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[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 YES;
}
#end
remote page code
hello
Tenth.h file
#import <UIKit/UIKit.h>
#interface Tenth : UIViewController <UIWebViewDelegate> {
IBOutlet UIWebView *category10;
}
-(IBAction)back;
#end
My first guess is that the Web view does not have its delegate set. In order for it to call
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
The class containing this method needs to be set as the webview's delegate. So somewhere in the code there should be a line similar to webView.delegate = <variable>, where the variable is the instance of the class which has implemented the shouldStartLoadWithRequest: method.
This is often "self" when the webView is a subview of a viewController's view. But the way you have described your application, I am not sure if it will be self or not, but it sounds like it will not be self, but the name of the instance of a different class.
Maybe try this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Remember to set web view delegate to self.
category10.delegate = self;
}

Set Delegate methods on child view controll

I am building an application which should allow the user to scroll through the images. Since I have many images (downloaded from the web), what i doing is I have UP and down button on the parent view, in addition i have the scroll view. Based on the selected option (up or down), I add the ImageClass ( created a class which extends UIViewController) view to the scroll view.
Now, on the selected view the user can mark a point or do any stuff.
The question is how from the parent view I can call methods of the Uiviewcontroller. I know how I can set the delegate methods but what I want is that parent controller can call any a method say redraw method which would redraw the entire view.
Code:
-(IBAction) down:(id) sender{
[scrollView2 removeFromSuperview];
}
-(IBAction) down :(id) sender {
[scrollView2 removeFromSuperview];
if(scrollView2 == nil)
scrollView2 = [[UIScrollView alloc] init];
[self.view addSubview:scrollView2];
[self.view sendSubviewToBack:scrollView2];
[scrollView2 setBackgroundColor:[UIColor blackColor]];
[scrollView2 setCanCancelContentTouches:NO];
scrollView2.clipsToBounds = YES;
// default is NO, we want to restrict drawing within our scrollview
scrollView2.indicatorStyle = UIScrollViewIndicatorStyleWhite;
// CSImageView is a class which of the type UIViewController
imageVie = [[CSImageView alloc] init];
[scrollView2 addSubview:imageVie.view];
[scrollView2 setContentSize:CGSizeMake(1500,1500)];
[scrollView2 setScrollEnabled:YES];
[imageView release];
}
Now, from the parent view controller I want to call say:
imageVie.redraw(); method
Code for CSImageView
#interface CSImageView : UIViewController {
NSNumber *imageId ;
}
#property (nonatomic, retain) NSNumber *venueId;
-(void) redraw;
#end
#implementation CSImageView
#synthesize imageId;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (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
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[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);
}
-(void) redraw {
NSLog(#"I am ehre in the test function");
}
#end
Can you please help me on the same. I am not able to call the redraw method. Any input would be appreciated.
First, CSImageView should probably be a subclass of UIView, not UIViewController. You should keep a reference to your instance (i.e. as an instance variable or synthesized property) so you can access it from methods other than - down:.
Wow.
I can't say I follow what you've coded, but here's how you do it.
During this part...add a tag to the view
// CSImageView is a class type UIViewController
imageVie = [[CSImageView alloc] init];
imageVie.tag = 99 // Any number. Preferably a constant
[scrollView2 addSubview:imageVie.view];
...
Then on the parent
view controller. You can ...
-(IBAction) down:(id) sender {
CSImageView *view = [scrollView2 viewWithTag:99];
[view redraw];
... }
Something like that.

Unable to load view on button press iPhone

I am unable to load the next view on button press. I have created a button and attached the checkButtonPress action to the button in the IB. But when I press the button on the simulator the next view (ViewOne.xib) do not load. When I tried to debug the code; it is printing the NSLog(#"View One");written in the if statement below which means the code is reaching to that point but the next view is not loading. I have already created the ViewOne .h, .m .xib files. Following is the code written in check1ViewController.m implementation file:
#import "check1ViewController.h"
#import "ViewOne.h"
#implementation check1ViewController
-(IBAction) checkButtonPress: (id) sender{
int button = [sender tag];
if(button==1)
{
NSLog(#"View One");
ViewOne *tempObj = [[ViewOne alloc]initWithNibName:#"ViewOne" bundle:nil];
[self.navigationController pushViewController:tempObj animated:YES];
[tempObj release];
}
else if(button==2)
{
NSLog(#"View Two");
}
}
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
- (void)dealloc {
[super dealloc];
}
#end
The code is running fine with no errors or warnings.
Any suggestions if I am missing any part in the IB or in the code to be written or do need to override any method in any of the file ... or did I misplace IBAction before any other method
Sorry but I am new to iPhone dev so not sure what I did wrong ?
Thanks in advance
You application is not having navigation controller so add next view on window for this make object of AppDelegate class and then access window to addView.
YourAppDelegate *obj=(YourAppDelegate *)[[UIApplication sharedApplication] delegate];
[obj.window addSubView:viewController.view];

How to add a custom iPhone UI element that is not an IB component?

I'm trying to create an application that uses the iPhone MapView (under Google Code). I can't figure out how to integrate this thing into my application without handwriting the entire UI, ie not using the IB at all.
How can I use the Interface builder to create all of my menus and such but add the MapView in? Do I need to edit the MapView to make it an IB component?
Thanks!
EDIT:
#pgb
Here is my code, it still just displays a blank UIView, I have connected everything up on the IB side.
//
// NewTestViewController.h
// NewTest
//
#import <UIKit/UIKit.h>
#interface NewTestViewController : UIViewController {
UIView* mapPlaceholder;
}
#property (nonatomic, retain) IBOutlet UIView* mapPlaceholder;
#end
//
// NewTestViewController.m
// NewTest
//
#import "NewTestViewController.h"
#import "MapView.h"
#implementation NewTestViewController
#synthesize mapPlaceholder;
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
MapView *mapView = [[[MapView alloc] initWithFrame:
[[UIScreen mainScreen] applicationFrame]] autorelease];
[mapPlaceholder addSubview:mapView];
}
return self;
}
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (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 {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[mapPlaceholder.subviews release];
[super dealloc];
}
#end
NEVERMIND FIGURED IT OUT THANGS PBG
You can probably create the whole interface in IB, add an empty UIView as the placeholder view, and then use addSubview: to add the MapView instance to the view hierarchy.
Your placeholder view can be defined as an IBOutlet, so you can then add the MapView from your UIViewController instance.
In IB you can add a UIView and then change the type of the view to any custom UIView - I'm assuming MapView subclasses UIView just as MKMapView does...
I'm trying to create an application that uses the iPhone MapView (under Google Code).
Why not use MapKit? Surely IB comes with an MKMapView in its Library.