how to pass touchesBegan from UIScrollView to UIViewController - iphone

Actually, I want to push data from one view to other. I have a UIScrollView which has images on top of it. Now I want to push the data from that view to other view since whenever I do touch on that image view I want to select the position and push the location to other view.
UIScrollView does not have navigationController and cannot be able to push it.
UIScrollView is on top of UIViewController class. Is there a way to send the UITouch from UIScrollView to UIViewController Class and let that class push the view or do I have to work around some thing.
I have the following code for UIScrollView class,
ImageScrollView.m
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
CGPoint touchInScrollView = [t locationInView:imageView];
NSLog(#"x: %f", floor(touchInScrollView.x));
NSLog(#"Y : %f", floor(touchInScrollView.y));
/****Cant be done since pushViewController is not allowed in UIScrollView.****/
DetailViewController *newView = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
[self.navigationController pushViewController:newView animated:YES];
}

Add this property to ImageScrollView.h
#property (nonatomic, retain) IBOutlet UIViewController* parentVC;
Add this line after #implementation in ImageScrollView.m
#synthesize parentVC;
Add this line to your - (void)dealloc method in ImageScrollView.m
[parentVC release];
If you create your ImageScrollView programmatically, after creation in your view controller:
imageScrollViewYouJustMade.parentVC = self;
If you create your ImageScrollView in Interface Builder, connect the parentVC outlet to File's Owner.
To push a new view controller, in ImageScrollView.m
[self.parentVC.navigationController pushViewController:newView animated:YES];
Here's an alternative,
I can't say for sure without knowing more about your application, but in general if I had a scroll view containing images that I wanted to tap, I would use a UIButton instead of UIImageView, and do something like
btnImage = [UIImage imageNamed:#"image.png"];
[btn setImage:btnImage forState:UIControlStateNormal];
If you aren't creating buttons programmatically, you can also set an image as it's background by changing the Type in the Attributes inspector to Custom, and change the Background attribute to the desired image.
Using a button instead of an image view will allow you to connect the touchDown outlet of the button to an IBAction method in your primary view controller that might look like:
- (IBAction)smileyFaceButtonTapped:(UIButton*)sender;

Related

ScrollView won't scroll after adding as subview

So i'm adding UIView with UIScrollView in it to another view by pressing segment tool:
UIView.h
#interface gettingELORolesViewController : UIViewController{
UIViewController *currentController;
NSMutableArray *viewControllers;
}
- (IBAction)SegmentToggle:(UISegmentedControl *)sender;
#property (strong, nonatomic) IBOutlet UIView *containerView;
UIView.m
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Storyboard_iPhone"
bundle:nil];
firstView *FirstView = [sb instantiateViewControllerWithIdentifier:#"firstOne"];
secondView *SecondView = [sb instantiateViewControllerWithIdentifier:#"secondOne"];
viewControllers = [NSMutableArray arrayWithObjects:FirstView,SecondView,nil];
currentController = FirstView;
[containerView addSubview:FirstView.view];//containerView = self.view
and then depends on what segment is chosen, it shows different view:
- (IBAction)SegmentToggle:(UISegmentedControl *)sender {
UIViewController *selectedView=nil;
if (sender.selectedSegmentIndex==0) {
selectedView= [viewControllers objectAtIndex:0]; // retrieve object at index 0 from viewControllers array
}
else if(sender.selectedSegmentIndex==1){
selectedView= [viewControllers objectAtIndex:1]; // retrieve object at index 1 from viewControllers array
}
[currentController.view removeFromSuperview]; // remove Current displaying view from superView
currentController=selectedView; // make selected View to be the current View
[containerView addSubview:selectedView.view]; // Add newly selected view on container View
}
secondView is tableViewController and everything is working great when i choose second segment. When i choose first one it shows up but scroll doesn't work and i don't know why.
firstView.m viewDidLoad method looks like this:
-(void)viewDidLoad{
[super viewDidLoad];
mainScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[mainScrollView setContentSize:CGSizeMake(320, 600)];
[mainScrollView setScrollEnabled:YES];
}
Paging is enabled in storyBoard. And it hooked up with .h file of firstView.
Please tell me what am i doing wrong.
When you call -SegmentToggle:,
you create a local variable called selectedView
you assign a view controller to selectedView depending on what segment is selected
the method ends, selectedView goes out of scope
In short, you're not doing anything. You should, at least, replace a view in the current view hierarchy with the view of the selected controller (and maybe stash a reference to the selected controller in an instance variable for later lookup?)
But taking a step back, it looks like you're trying to create a view controller that manages other view controllers. There are now very specific rules around that as of iOS 5. Please watch the WWDC 2011 video called "Implementing UIViewController Containment" for more information and examples.

Add target for UIView Programmatically

In my view I want to add a target which should be fired when I click the view. I can do the same through IB or I have done it for buttons even in code. However I have no idea how to do it for UIView programatically.
Anyone has done that before.
Help me.
For clicking a UIView you have to use UIGestureRecognizer or UITouch. This would only help in prompting an action. The UIButton has a selector method whereas the UIView does not have any such method. Also , this is same for UIImageViews etc also.
You can acheive this using UIGestureRecognizer.
Step 1:
Add your UIView as a property in your viewcontroller
#property (strong, nonatomic) IBOutlet UIView *yourView;
Step 2:
Set UIGestureRecognizer for your UIView.
- (void)viewDidLoad {
[super viewDidLoad];
UIGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[self.yourView addGestureRecognizer:gesture];
}
Step 3:
Handle the click on UIView.
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
//to get the clicked location inside the view do this.
CGPoint point = [gestureRecognizer locationInView:self.yourView];
}
Remember that A UIGestureRecognizer is to be be used with a single view.

How to put an UITableViewController in UIView to make touchesBegan to work in iPhone?

I create & present modally an UITableViewController(say Table2) class from another UITableViewController class(say Table1) like this..
-(void)createTable2 {
Table2Controller *table2Controller = [ [Table2Controller alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:table2Controller];
[self.navigationController presentModalViewController:nav animated:YES];
[nav release];
[table2Controller release];
}
So the Table2 will be shown. I want to use touchesBegan method to resign keyboard in Table2 because i have some UITextField as cells. I included UITextFieldDelegate protocol in .h file of Table2.
But i knew that these touchesBegan method will work only with UIView & not with UIViewController(Am i right?). But i dont know where & how(I tried in the createTable2 function itself. It does not work) to add an UIView and then add Table2 in that UIView to do things happen... Any advice....
Your table view controller has a table view property. You can subclass the table view and then override methods such as -touchesBegan:withEvent:. Instantiate your custom table view and set this instance to the view property.
UIViewController controls the UIView and other UI elements presented on the screen. All those elements can respond to touches thanks to UIResponder class that they are subclassing.
Use Table2Controller to override touchesBegan method to control the touch events that happen on any UI element within this viewController.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[inputTV resignFirstResponder];
[super touchesBegan:touches withEvent:event];
}
Note always call super method declaration so that your touch can travel up the respond chain.

Problem in connecting IBOutlet

In my application, I am trying to remove all existing subviews and add a new one created in Interface Builder. However, I don't seem to be able to connect the view.
When a button clicks, the following function is executed (inside a subclass of UIViewController):
// Display a list of settings to choose from
- (void) settings
{
SettingsRootController *settingsController = [[SettingsRootController alloc] initWithNibName:#"SettingsRootController" bundle:nil];
_settingsController = settingsController;
for (UIView *view in self.view.subviews)
{
[view removeFromSuperview];
}
[self.view addSubview:_settingsController.view2];
int a = [self.view.subviews count];
[self.view setNeedsDisplay];
......
}
#import <UIKit/UIKit.h>
#interface SettingsRootController : UIViewController
{
IBOutlet UIView *_view2;
}
#property(nonatomic, retain) IBOutlet UIView *view2;
Inside the Interface Builder, I created a new View-based xib. Set file owner to SettingsRootController. Randomly drag a UITextView into the xib. Connect the UITextView to view and view2 in SettingsRootController.
However, if the above line is:
[self.view addSubview:_settingsController.view2];
a would always be 0, and thus the new screen is empty.
But if change to:
[self.view addSubview:_settingsController.view];
I could see the UITextView.
When you create a view controller, its view will not be created at initialisation time. The view will be created at first access of the view property. Thats why it works when you use _settingsController.view. But when you access view2 the view will not be loaded. You could write a custom getter method like:
-(UIView*) view2 {
_view2 = self.view;
return _view2;
}
The instance var declaration is different from the property declaration! With and without underscore. Maybe thats why it doesn't work.

How to implement multiple UIView classes in single UIViewController

In my viewbased application i loaded oneview as mainview and another view as subview of mainview. Its work well the code snippet is ,
In mainviewcontroller,
IBOutlet UIView *subView;
#property(nonatomic,retain) UIView *subView;
#synthesize subView;
[subView release];
//add subview
[self.view addSubview:subView];
//removefromsubview
[subView removeFromSuperview];
This code works fine.....
I dont want to create subview in mainviewcontroller, so i created a new UIView class and its named as subView, now i deleted all declarations of subView from mainviewcontroller and just import subView class in mainviewcontroller. And using this [self.view addSubview:subView];
This things not work great. Can anyone help me ... How can i interact a separate UIView class with UIViewcontroller.One more thing is that UIView class have labels and textboxes can i set values from UIViewController to UIView labels and textboxes ......
Is it possible ?
Thanks in advance.......Sorry for my bad english
You have a sub-class called Subview which is declared as a UIView, i.e.
#interface Subview : UIView {
UILabel *foo;
}
#property (nonatomic, retain) UILabel *foo;
#end
Now you want to use this sub-class inside of your main UIView, which you had from the start. There are a few things you need to do.
#import the Subview in your header file, and add an instance of it to your class.
#import "Subview.h"
and inside of your #interface's {}'s,
Subview *mySubview;
In the viewDidLoad class for your main view controller, around the bottom, add something like:
mySubview = [[Subview alloc] init];
[self.view addSubview:mySubview];
[mySubview release];
First line will allocate a new "Subview" for you, second line will add this to your view so you get the stuff it has, and third line will release it. It's okay to release it here, because "self.view" will now be responsible for it, so it won't vanish.
Lastly you need to set the view up in the init method for Subview. In Subview.m, do something like:
- (id)init
{
if (self = [super init]) {
foo = [[UILabel alloc] init];
foo.text = #"Hello!";
[self addSubview:foo];
}
return self;
}
And I think that should take care of it. You also want to release foo in -dealloc for Subview but you probably know how to do that stuff already.