Cannot drag an object when subclassing UIScrollView in iOS 5, help? - ios5

First of all, this problem did not exist in iOS 4.3. I can still run the program in iOS 4.3 and won't see any problem. Secondly, this is an iPad app.
The problem is that when I hold down an image and drag it, it won't be dragged. It worked in iOS 4.3 but not iOS 5.
I created new testing project and cleared everything that's not needed. The project I chose is a Single View Application and did not alter any of the AppDelegate files.
Here is the code.
myUIScrollViewClass.h
#import <UIKit/UIKit.h>
#interface myUIScrollViewClass : UIScrollView
{
}
#end
myUIScrollViewClass.m
#import "myUIScrollViewClass.h"
#implementation myUIScrollViewClass
- (id)init
{
self = [super init];
if (self)
{
}
return self;
}
- (void)didReceiveMemoryWarning
{
[self didReceiveMemoryWarning];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.nextResponder touchesBegan: touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.nextResponder touchesMoved: touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.nextResponder touchesEnded: touches withEvent:event];
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.nextResponder touchesCancelled: touches withEvent:event];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#import "myUIScrollViewClass.h"
#interface ViewController : UIViewController <UIScrollViewDelegate>
{
myUIScrollViewClass *mainScrollView_;
UIImageView *aTouchedImage_;
}
#property (retain, nonatomic) myUIScrollViewClass *mainScrollView_;
#property (retain, nonatomic) UIImageView *aTouchedImage_;
#end
ViewController.m
#import "ViewController.h"
#implementation ViewController
#synthesize mainScrollView_;
#synthesize aTouchedImage_;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
mainScrollView_ = [[myUIScrollViewClass alloc] initWithFrame:self.view.frame];
[self.view addSubview:mainScrollView_];
mainScrollView_.delegate = self;
mainScrollView_.contentSize = CGSizeMake(1024, 768);
mainScrollView_.clipsToBounds = YES;
mainScrollView_.bounces = NO;
mainScrollView_.bouncesZoom = NO;
mainScrollView_.showsVerticalScrollIndicator = NO;
mainScrollView_.showsHorizontalScrollIndicator = NO;
mainScrollView_.backgroundColor = [UIColor whiteColor];
mainScrollView_.userInteractionEnabled = YES;
aTouchedImage_ = [[UIImageView alloc] initWithImage: [UIImage imageNamed:#"image1.png"]];
[aTouchedImage_ setFrame:CGRectMake(0, 0, 80, 80)];
[mainScrollView_ addSubview:aTouchedImage_];
[aTouchedImage_ setCenter:CGPointMake(512, 334)];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)anEvent
{
mainScrollView_.scrollEnabled = NO;
for (UITouch *touch in touches)
{
[aTouchedImage_ setCenter:[touch locationInView:self.view]];
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)anEvent
{
mainScrollView_.scrollEnabled = NO;
for (UITouch *touch in touches)
{
[aTouchedImage_ setCenter:[touch locationInView:self.view]];
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)anEvent
{
mainScrollView_.scrollEnabled = YES;
for (UITouch *touch in touches)
{
}
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)anEvent
{
mainScrollView_.scrollEnabled = YES;
for (UITouch *touch in touches)
{
}
}
#end

It seems I will answer my own question.
I have requested a support from Apple Developer Technical Support, and they told me to place my code in the UIScrollView rather than passing the touch events to another view. Apple themselves admitting that there is a problem with passing touch events.
Here is an extract of their reply:
"It looks like not all touch events are getting through to your view controller. Your UIScrollView is blocking touch events from getting through, even though is forwards those events to the next responder. The behaviour is very erratic, some touch events are being forwarded to your view controller, but not all of them."
"Looks like a behaviour change in iOS 5.0.x. My guess it's because of the view controller containment feature that was introduced."
The other way to do it is to use UIGestureRecognizer to implement dragging of views. Something like the code below:
- (void)viewDidLoad
{
// ... other initialization code here
UILongPressGestureRecognizer *longPress = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(dragChild:)] autorelease];
[longPress setMinimumPressDuration:0]; // recognize immediately when a finger comes down
[draggableView addGestureRecognizer:longPress];
}
- (void)dragChild:(UILongPressGestureRecognizer *)longPress
{
[[longPress view] setCenter:[longPress locationInView:[[longPress view] superview]];
}

Related

how to convert UIView code into UIViewController with Nib in ipad

I have found tutorial which I want to implement in my view controller but the code is written in UIView so how to convert UIView code into UIViewController it can work here is my code
#import <UIKit/UIKit.h>
#interface MyLineDrawingView : UIView {
UIBezierPath *myPath;
UIColor *brushPattern;
}
#end
#import "MyLineDrawingView.h"
#implementation MyLineDrawingView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor=[UIColor whiteColor];
myPath=[[UIBezierPath alloc]init];
myPath.lineCapStyle=kCGLineCapRound;
myPath.miterLimit=0;
myPath.lineWidth=10;
brushPattern=[UIColor redColor];
}
return self;
}
Only override drawRect: if you perform custom drawing.
An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
[brushPattern setStroke];
[myPath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
// Drawing code
//[myPath stroke];
}
#pragma mark - Touch Methods
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
[myPath moveToPoint:[mytouch locationInView:self]];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
[myPath addLineToPoint:[mytouch locationInView:self]];
[self setNeedsDisplay];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//handle touch event
}
Create a UIViewController Object and set the view property to this view. Something like this should work.
UIViewController *vc = [[UIViewController alloc] init];
MyLineDrawingView *myView = [[MyLineDrawingView alloc] init];
vc.view = myView;

Image movement through touch is not working

I am using two images named "ATrackThumb" & "BTrackThumb" in my iPad application, to be moved by the touch of an user. I am using some methods for this purpose. But image movement is not working.
Methods are:
#pragma mark responding to touch events
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
for (UITouch *touch in touches) {
CGPoint t = [touch locationInView:touch.view];
if(t.x > (ATrackThumb.center.x-25) && t.x < (ATrackThumb.center.x+25) && t.y > (ATrackThumb.center.y-25) && t.y < (ATrackThumb.center.y+25)){
ASliderLastTouch = touch;
}
if(t.x>(BTrackThumb.center.x-25) && t.x < (BTrackThumb.center.x+25) && t.y > (BTrackThumb.center.y-25) && t.y < (BTrackThumb.center.y+25)){
BSliderLastTouch = touch;
}
}
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event{
for (UITouch *touch in touches) {
CGPoint t = [touch locationInView:touch.view];
//Check Slider for Contact
if(touch==ASliderLastTouch){
if(t.x>205)
[ATrackThumb setCenter:CGPointMake(205,ATrackThumb.center.y)];
else if(t.x<24)
[ATrackThumb setCenter:CGPointMake(24,ATrackThumb.center.y)];
else
[ATrackThumb setCenter:CGPointMake(t.x,ATrackThumb.center.y)];
hourSlider.value=(ATrackThumb.center.x-24)/15;
[self updateHour];
}
if(touch==BSliderLastTouch){
if(t.x>205)
[BTrackThumb setCenter:CGPointMake(205,BTrackThumb.center.y)];
else if(t.x<24)
[BTrackThumb setCenter:CGPointMake(24,BTrackThumb.center.y)];
else
[BTrackThumb setCenter:CGPointMake(t.x,BTrackThumb.center.y)];
minutesSlider.value=(BTrackThumb.center.x-24)/3.0;
[self updateMinute];
}
}
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event{
for (UITouch *touch in touches) {
if(touch==ASliderLastTouch)ASliderLastTouch=nil;
if(touch==BSliderLastTouch)BSliderLastTouch=nil;
}
}
where is the problem?
Following code is use for move image on your touch
AppDelegate Classes
**// .h File**
#import <UIKit/UIKit.h>
#class UITouchTutorialViewController;
#interface UITouchTutorialAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UITouchTutorialViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITouchTutorialViewController *viewController;
#end
//////////////////////////////////////////////////////////////////////////////////
// .m File
#import "UITouchTutorialAppDelegate.h"
#import "UITouchTutorialViewController.h"
#implementation UITouchTutorialAppDelegate
#synthesize window;
#synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
//////////////////////////////////////////////////////////////////////////////
UIViewController Classes
// .h file
#import <UIKit/UIKit.h>
#interface UITouchTutorialViewController : UIViewController {
IBOutlet UIImageView *cloud;
}
#end
// .m File
#import "UITouchTutorialViewController.h"
#implementation UITouchTutorialViewController
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
cloud.center = location;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesBegan:touches withEvent:event];
}
/*
// Override initWithNibName:bundle: to load the view using a nib file then perform additional customization that is not appropriate for viewDidLoad.
- (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.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[super dealloc];
}
#end

How to Move Pencil Image using UITouch? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I want to Move pencil image using UITouch? I want to move pencil and it will write whatever we want.
But I am not able to move and write Pencil image.
Any hints from experts would be very welcome.
Following code is use for move image on your touch
AppDelegate Classes
**// .h File**
#import <UIKit/UIKit.h>
#class UITouchTutorialViewController;
#interface UITouchTutorialAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UITouchTutorialViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITouchTutorialViewController *viewController;
#end
//////////////////////////////////////////////////////////////////////////////////
// .m File
#import "UITouchTutorialAppDelegate.h"
#import "UITouchTutorialViewController.h"
#implementation UITouchTutorialAppDelegate
#synthesize window;
#synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
//////////////////////////////////////////////////////////////////////////////
UIViewController Classes
// .h file
#import <UIKit/UIKit.h>
#interface UITouchTutorialViewController : UIViewController {
IBOutlet UIImageView *cloud;
}
#end
// .m File
#import "UITouchTutorialViewController.h"
#implementation UITouchTutorialViewController
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
cloud.center = location;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesBegan:touches withEvent:event];
}
/*
// Override initWithNibName:bundle: to load the view using a nib file then perform additional customization that is not appropriate for viewDidLoad.
- (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.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[super dealloc];
}
#end
Use these methods:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self];
yourPencilImgView.center = [touch locationInView:self];
}
And
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self];
yourPencilImgView.center = currentPoint;
}
You can use UIPanGestureRecognizer
- (void)onDraggingPencil:(UIPanGestureRecognizer *)panGR {
CGPoint translation = [panGR translationInView:baseView];
if (panGR.state == UIGestureRecognizerStateBegan) {
} else if (panGR.state == UIGestureRecognizerStateChanged) {
CGRect _rect = panGR.view.frame;
_rect.origin.x = dragPoint.x + translation.x;
_rect.origin.y = dragPoint.y + translation.y;
panGR.view.frame = _rect;
} else if (panGR.state == UIGestureRecognizerStateEnded) {
}
}
You can drag and drop an image using below code
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[imageView_ addGestureRecognizer:panRecognizer];
-(void)move:(id)sender {
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
firstX = [[sender view] center].x;
firstY = [[sender view] center].y;
}
translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY+translatedPoint.y);
[[sender view] setCenter:translatedPoint];
}

Cant get UIButton to highlight with TapGestureRecognizer

I've setup a tap gesture recognizer and add the recognizer to the uibutton. The button has a background image. When I tap the button it doesn't highlight at all, the only thing I've been able to get it to do is change it's alpha value.
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
singleTap.cancelsTouchesInView = NO;
[btnNext addGestureRecognizer:singleTap];
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
UIView *tappedView = [gesture.view hitTest:[gesture locationInView:gesture.view] withEvent:nil];
NSLog(#"Touch event view: %#",[tappedView class]);
UIButton *myButton = (UIButton *) tappedView;
[self highlightButton:myButton];
tappedView.alpha = 0.5f;
}
Any would be appreciated. Thanks
You can intercept the touches events with a gesture recognizer, and then programmatically add the recognizer to all your uibuttons. For instance:
//
// HighlighterGestureRecognizer.h
// Copyright 2011 PathwaySP. All rights reserved.
//
#import <Foundation/Foundation.h>
#interface HighlightGestureRecognizer : UIGestureRecognizer {
id *beganButton;
}
#property(nonatomic, assign) id *beganButton;
#end
and the implementation:
//
// HighlightGestureRecognizer.m
// Copyright 2011 PathwaySP. All rights reserved.
//
#import "HighlightGestureRecognizer.h"
#implementation HighlightGestureRecognizer
#synthesize beganButton;
-(id) init{
if (self = [super init])
{
self.cancelsTouchesInView = NO;
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.beganButton = [[[event allTouches] anyObject] view];
if ([beganButton isKindOfClass: [UIButton class]]) {
[beganButton setBackgroundImage:[UIImage imageNamed:#"grey_screen"] forState:UIControlStateNormal];
[self performSelector:#selector(resetImage) withObject:nil afterDelay:0.2];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)reset
{
}
- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event
{
}
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer
{
return NO;
}
- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer
{
return NO;
}
- (void)resetImage
{
[beganButton setBackgroundImage: nil forState:UIControlStateNormal];
}
#end
The way you'd add the gesture recognizer to your button would be like so:
HighlighterGestureRecognizer * tapHighlighter = [[HighlighterGestureRecognizer alloc] init];
[myButton addGestureRecognizer:tapHighlighter];
[tapHighlighter release];
So basically you're declaring it, initializing it, and then adding it. After that, you'll want to release it, since the addGestureRecognizer retains it.
Also simply try
adjustsImageWhenHighlighted = YES set on your buttons? The default is YES, but maybe you changed it in the xib. It's the "Highlighted Adjusts Image" checkbox in the attributes inspector:

Automatically show text cursor in UISearchBar

Is it possible to always show text cursor in UISearchBar (not only after touch)?
add this
- (void)viewDidAppear:(BOOL)animated {
[mySearchBar becomeFirstResponder];
[super viewDidAppear:animated];
}
Also try this...
- (void)viewDidAppear:(BOOL)animated {
[mySearchBar becomeFirstResponder];
[super viewDidAppear:animated];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[mySearchBar becomeFirstResponder];
}