Using UITouch To Drag A UITextField Around The Screen on iPhone - iphone

I am developing a sample application, where I have a situation for moving a UITextFields, UILabels etc., across the screen. I am not able to find any resource for implementing this.
I want to implement like this for a UITextField

Since you have an excellent tutorial on dragging already, I will assume your problem is the keyboard that comes up when you try to drag a UITextField instead of a UIView. The solution should be pretty simple: myTextField.userInteractionEnabled = NO; - that should disable user interaction and make it "read only". Perhaps have an edit mode where all text fields get this flag set. If it causes trouble, then add the textField to a UIView and then set the userInteractionEnabled to false. Then you can drag the UIView and it will drag the text field with it.

I followed Michael's suggestion and got the solution.I have given the code snippets below which will be useful for those who need to implement the same.
Steps:
Choose windows based application,then create a UIViewController subclass and add it to the window in the appdelegate file.
In the XIB of the viewcontroller class you created add UIViews and add the controls like textfield etc.,to the UIViews that you have created.We are going to move these views only,so add IBOutlets in the .h file of the view controller subclass and map them to the IB accordingly.
Sample Code
appdelegate.h
#import <UIKit/UIKit.h>
#import "MyView.h"
#interface MyAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
MyView *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
appdelegate.m
#import "MyAppDelegate.h"
#implementation MyAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch.
viewController=[[MyView alloc]init];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
viewcontroller.h
#import <UIKit/UIKit.h>
#interface MyView : UIViewController {
IBOutlet UIView *textFieldView;
IBOutlet UIView *labelView;
}
#end
viewcontroller.m
#import "MyView.h"
#implementation MyView
- (void)viewDidLoad {
[self.view addSubview:textFieldView];
[self.view addSubview:labelView];
[super viewDidLoad];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// get touch event
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if ([touch view] == textFieldView) {
// move the image view
textFieldView.center = touchLocation;
}
if ([touch view] == labelView) {
// move the image view
labelView.center = touchLocation;
}
}
- (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
Thank u all.Have a niece time.

Related

iOS pan recogniser added through interface builder

I say first that I'm completely new to objectiveC and am also working with interface builder the first time.
I just want to make the pan gesture work (I will need the zoom gesture also for what I really want to do but I thought if I start with the easier pan).
I followed some tutorial but it still doesn't work neither on my iPhone 5 nor in the simulator.
I've started the thing based on a page based application. I then established a new view and a view controller for that one. Then I dragged and dropped the Pan Gesture from Interface builder to the view. User Interaction on the view is enabled.
Here is my code:
uACropViewController.h
#import <UIKit/UIKit.h>
#interface uACropViewController : UIViewController
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer;
#property (weak, nonatomic) IBOutlet UIImageView *CropImage;
#property (strong, nonatomic) IBOutlet UIPanGestureRecognizer *onGestureAction;
#end
uACropViewController.m
#import "uACropViewController.h"
#interface uACropViewController ()
#end
#implementation uACropViewController
#synthesize CropImage;
static CGPoint originalPoint;
- (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.
//for resetting the center of the image, when the pan gesture is ended.
originalPoint=CropImage.center;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)onGestureAction:(id)sender{
if ([sender isKindOfClass:[UIPanGestureRecognizer class]]) {
//is a pan gesture
UIPanGestureRecognizer *recognizer=(UIPanGestureRecognizer *)sender;
if (recognizer.state==UIGestureRecognizerStateBegan||recognizer.state==UIGestureRecognizerStateChanged) {
CGPoint nextPoint= [recognizer translationInView:self.view];
CGPoint currentPoint=CropImage.center;
currentPoint.x +=nextPoint.x;
currentPoint.y +=nextPoint.y;
CropImage.center=currentPoint;
[recognizer setTranslation:CGPointZero inView:self.view];
}
if (recognizer.state==UIGestureRecognizerStateEnded) {
CropImage.center=originalPoint;
[recognizer setTranslation:CGPointZero inView:self.view];
}
return;
}
}
#end
To be honest I have no idea of what's going wrong here. so any help or pointers are appreciated!
thanks,
Suse
The IBOutlet is the reference to that object in the view, the IBAction is the action that is called when an event is triggered on that variable.
For example, you can have a UIButton IBOutlet to change properties of the UIButton like the size, and a UIButton IBAction to recognise when the button is pressed.
In your case, onGestureAction is a variable that points to that gesture recognizer, and hanldePan: is the action responder.
Try adding the method here:
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer
{
if (recognizer.state==UIGestureRecognizerStateBegan||recognizer.state==UIGestureRecognizerStateChanged) {
CGPoint nextPoint= [recognizer translationInView:self.view];
CGPoint currentPoint=CropImage.center;
currentPoint.x +=nextPoint.x;
currentPoint.y +=nextPoint.y;
CropImage.center=currentPoint;
[recognizer setTranslation:CGPointZero inView:self.view];
}
if (recognizer.state==UIGestureRecognizerStateEnded) {
CropImage.center=originalPoint;
[recognizer setTranslation:CGPointZero inView:self.view];
}
return;
}

UIScrollView won't scroll when re-entering view

I have a UIView (inside a View Controller, of course), and inside this UIView, I have a UIScrollView. UIScrollView contains some images and buttons. One of the buttons uses the modal Action Segue and opens up a UIView with a MapView inside, and a "back" button at the bottom that takes you back to the previous UIView. But upon going "back" (from the MapView to the UIView), the UIScrollView does not scroll anymore like it did before going to the MapView and back. It's like it's locked in its top position. I feel like it has something to do with delegates? I dunno though, I'm not too clear on those yet. Anyway, any insight to my scrolling issue?? Thanks!!
Here's my .h file (where my scroll view is):
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface ThirdViewController : UIViewController <UIScrollViewDelegate, UIScrollViewAccessibilityDelegate>
#property (strong, nonatomic) IBOutlet UIView *findUsView;
#property (weak, nonatomic) IBOutlet UIScrollView *findUsScrollView;
- (IBAction)callButton:(id)sender;
- (IBAction)getDirButton:(id)sender;
#end
Here's my .m file (where my scroll view is):
#import "ThirdViewController.h"
#implementation ThirdViewController
- (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.
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"appBackgroundColor.png"]];
[self.view addSubview:self.findUsScrollView];
}
-(void)viewWillAppear:(BOOL)animated{
//this line creates the frame of the scrollview (dimensions)
[self.findUsScrollView setFrame:CGRectMake(0, 0, 0, 750)];
[super viewWillAppear:animated];
}
-(void)viewDidAppear:(BOOL)animated
{
//dimensions of content within scrollveiw. Scrolling enabaled.
[self.findUsScrollView setScrollEnabled:YES];
[self.findUsScrollView setContentSize:CGSizeMake(0, 751)];
[super viewWillAppear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)callButton:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:0000000000"]];
}
- (IBAction)getDirButton:(id)sender {
}
#end
Here's the .h file for the Map View:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MyMapViewController : UIViewController <MKMapViewDelegate, MKAnnotation>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (weak, nonatomic) IBOutlet UINavigationBar *titleBarMap;
#property (weak, nonatomic) IBOutlet UIToolbar *bottomNavBarMap;
#property (weak, nonatomic) IBOutlet UIView *topTitlesOverlay;
- (IBAction)backButtonMap:(id)sender;
#end
Here's the .m file for the Map View:
#import "MyMapViewController.h"
#implementation BountMapViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (IBAction)backButtonMap:(id)sender {
[self dismissViewControllerAnimated:YES completion: ^(void){
ThirdViewController *vc = (ThirdViewController *)[self presentingViewController];
[[vc findUsScrollView] becomeFirstResponder];
}];
}
#end
Try moving [self.findUsScrollView setFrame:CGRectMake(0, 172, 320, 680)]; and [self.findUsScrollView setContentSize:CGSizeMake(320, 680)]; to viewDidLoad as a first suggestion. You don't want those to be called everytime your view appears.
Second, your contentSize and frameSize are the same (320, 680). This means your UIScrollView does not need to scroll. Remember: for a UIScrollView to scroll it's content size must be bigger than it's frame size. That should be all, and of course: setScrollEnabled: YES;
Your override of viewDidAppear is calling [super viewWillAppear:] instead of [super viewDidAppear:]

Many-to-one UIViewController communication. Navigation Controller Push View. Delegate or NSNotificationCenter or Class Method?

I have a UIViewController "NavigationViewController" that is added as a subview of my "FirstViewController" that takes up the whole screen (i.e. similar to the Flipboard Navigation controller in the iPad application). Many views are added and removed based on what selection the user makes. I want to be able to push a view controller to the "FirstViewController" navigationController from within the "many views" that are added. In this case the "FeaturedViewController" is one of those many views that can be selected. It inherits ContentViewController where the delegate protocol is defined.
TL;DR I want to access the navigationcontroller in the first view to push a view from the added subview "FeaturedViewController".
Here is a visual representation:
Here is the my code from:
Here is my current attempt that does not work. Note, I took some code out relating to the "Navigation Controller"
/* First View Controller */
#import <UIKit/UIKit.h>
#import "ContentViewController.h"
#interface ViewController : UIViewController <BaseViewDelegate, ContentViewDelegate>
{
IBOutlet UINavigationController *navigationController;
ContentViewController *contentView;
}
#property (strong, nonatomic) IBOutlet UINavigationController *navigationController;
#property (strong, nonatomic) ContentViewController *contentView;
---------------------------------------------------------
#import "ViewController.h"
#import "NavigatorViewController.h"
#import "BinViewController.h"
#implementation ViewController
#synthesize navigationController, contentView;
static NSArray *viewArray = nil;
- (void)didReceiveMemoryWarning
{
[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, typically from a nib.
self.navigationController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:navigationController.view];
// Navigation View is used to navigate throughout the entire application
NavigatorViewController *navController = [[NavigatorViewController alloc] init];
contentView = [[ContentViewController alloc] init];
contentView.delegate = self;
// Add the views to the array (using ARC)
viewArray = [NSArray arrayWithObjects:navController, contentView, nil];
}
-(void)displayNavigator
{
// Get the right view controller
UIViewController *viewController = [viewArray objectAtIndex:0];
// Add the subview to the view
[self.view addSubview:viewController.view];
}
-(void)pushViewController:(UIViewController *)viewController
{
NSLog(#"First View Push View Controller called");
[self.navigationController pushViewController:viewController animated:YES];
}
#end
/* Content View Controller */
#class ContentViewController;
#protocol ContentViewDelegate <NSObject>
-(void)pushViewController:(UIViewController *)viewController;
#end
#interface ContentViewController : UIViewController
{
__weak id <ContentViewDelegate> delegate;
}
#property (weak) __weak id <ContentViewDelegate> delegate;
- (void)pushView:(UIViewController *)viewController;
#end
---------------------------------------------------------
#import "ContentViewController.h"
#import "BinViewController.h"
#implementation ContentViewController
#synthesize delegate;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)pushView:(UIViewController *)viewController
{
NSLOG(#"Push View from ContentViewController");
if ([delegate respondsToSelector:#selector(pushViewController)])
[delegate pushViewController];
}
#end
/* View that is added to the navigator view (it inherits ContentViewController where the delegate protocol is defined)*/
#import <UIKit/UIKit.h>
#import "ContentViewController.h"
#interface FeaturedViewController : ContentViewController <CustomPagingDelegate>
#end
---------------------------------------------------------
#import "FeaturedViewController.h"
#import "BinViewController.h"
#implementation FeaturedViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void) touchUpInsideItemAtIndex:(NSUInteger)itemIndex
{
// [[[[[self view] superview] superview] superview] removeFromSuperview];
NSLOG(#"Touch up inside from featured view");
BinViewController *binViewController = [[BinViewController alloc] init];
[self pushView:binViewController];
}
#end
Many to one or one to many sounds like easiest route would be to use NSNotificationCenter.

Double Tap inside UIScrollView to Another View

I want to preface this question with the fact I am new to the iphone application development and many times believe I may be over my head. I am trying to find an action that will allow me to double tap anywhere within my full screen UIScrollView to return to my main menu (MainMenuViewController).
I currently have the following code running for my ScrollViewController...
ScrollViewController.h
#import <UIKit/UIKit.h>
#interface ScrollViewController : UIViewController <UIScrollViewDelegate>
{
}
#end
ScrollViewController.m
#import "ScrollViewController.h"
UIScrollView *myScrollView;
UIPageControl *myPageControl;
#implementation ScrollViewController
- (void)loadScrollViewWithPage:(UIView *)page
{
int pageCount = [[myScrollView subviews] count];
CGRect bounds = myScrollView.bounds;
bounds.origin.x = bounds.size.width * pageCount;
bounds.origin.y = 0;
page.frame = bounds;
[myScrollView addSubview:page];
}
...etc
Any advice or sample code to implement a double tap within the ScrollView Controller to allow me to return to my MainMenuViewController would be greatly appreciated. Also please include any Interface Builder changes to the view (if necessary). I have been pouring over the forums for days and have not been able to successfully implement this action. Thanks...R.J.
First of all, create a subclass of a UIScrollView:
#import <UIKit/UIKit.h>
#interface MyScrollView : UIScrollView {
}
#end
Implement it:
#import "MyScrollView.h"
#implementation MyScrollView
- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event {
if (!self.dragging) {
[self.nextResponder touchesEnded: touches withEvent:event];
}
[super touchesEnded: touches withEvent: event];
}
- (void)dealloc {
[super dealloc];
}
#end
Then, use this subclass instead of a normal UIScrollView in your main View Controller. This will call the touchesEnded:withEvent: method (alternatively, you can call any method you want). Then, track for double taps (if you need info on how to do that, let me know).

SubViews not properly initialized using IB

I'm having trouble getting my SubViews properly initialized using Interface Builder. I have the following View hierarchy (UIWindow -> BlankCanvasView -> StalkerView). BlankCanvasView is a subclass of UIView and StalkerView is a IBOutlet of BlankCanvasView
#interface BlankCanvasView : UIView {
IBOutlet UIView *stalker;
}
#end
I've established a connection between the stalker outlet of BlankCanvasView and the subview. However, in my touchesBegin method of BlankCanvasView the stalker outlet is nil. See below for touchesBegin.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"Touch Begin detected!!!");
NSLog(#"Stalker instance %#", stalker);
[UIView beginAnimations:#"StalkerAnimation" context:nil];
UITouch *touch = [touches anyObject];
//stalker is nil here!!!
[stalker setCenter:[touch previousLocationInView:self]];
[UIView commitAnimations];
}
What am I missing? It looks like none of my demo apps are properly loading any subviews when I try and follow examples on iTunesU.
If you are creating your 'stalker' view in IB, it must be part of the view hierarchy (that is, added as a subview of another view), or it must be retained by your code in order for it to not be released after loading. If you use a retain property for your stalker variable, this will be taken care of for you, automatically:
#interface BlankCanvasView : UIView
{
UIView *stalker;
}
#property (nonatomic, retain) IBOutlet UIView *stalker;
#end
Make sure you #synthesize stalker; in your BlankCanvasView's implementation, and set the property to nil when you're deallocating your view:
#implementation BlankCanvasView
#synthesize stalker;
- (void)dealloc
{
self.stalker = nil;
[super dealloc];
}
#end