set up UITouch's moving range - ios

I create a touch moving event for a label which size is (30, 50). here is the code
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
UIView *superView = self.superview;
}
But I need to make sure the label can only move inside the superview. In other word, UILabel will stop moving when it “touch” the edge of view, How to setup label's moving range?

Set the label to your touch position
Check whether the label's frame is inside of the superView
If it is outside,change the frame,and set userInteractionEnabled to NO
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
self.center = [touches.anyObject locationInView:self.superview];
CGRect bounds = self.superview.bounds;
CGRect newFrame = self.frame;
if (newFrame.origin.x < 0) {
newFrame.origin.x = 0;
self.userInteractionEnabled = NO;
}
if (newFrame.origin.y<0) {
newFrame.origin.y = 0;
self.userInteractionEnabled = NO;
}
if (newFrame.origin.x + newFrame.size.width > bounds.size.width) {
newFrame.origin.x = bounds.size.width - newFrame.size.width;
self.userInteractionEnabled = NO;
}
if (newFrame.origin.y + newFrame.size.height > bounds.size.height) {
newFrame.origin.y = bounds.size.height - newFrame.size.height;
self.userInteractionEnabled = NO;
}
self.frame = newFrame;
}

Related

How to keep imageview inside UIView when moving imageview?

I have an UIView inside main view controller which contain 1 imageview.i moved imageview with this method.
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *aTouch = [touches anyObject];
if (aTouch.view == self.sub_View) {
CGPoint location = [aTouch locationInView:self.sub_View];
CGPoint previousLocation = [aTouch previousLocationInView:self.sub_View];
self.imageView.frame = CGRectOffset(self.imageView.frame, (location.x - previousLocation.x), (location.y - previousLocation.y));
}
}
Imageview move perfect. But i have to keep imageview inside UIView when i moved. Problem with this code is when i move imageview it is also moved outside UIView. I have to keep imageview inside UIView and movable only inside UIView.
Please help me to solve this. How to set boundary for imageview so it is movable only inside UIView.
Try below code.
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *aTouch = [touches anyObject];
if (aTouch.view == self.sub_View) {
CGPoint location = [aTouch locationInView:self.sub_View];
CGPoint previousLocation = [aTouch previousLocationInView:self.sub_View];
CGRect newFrame = CGRectOffset(self.imageView.frame, (location.x - previousLocation.x), (location.y - previousLocation.y));
if(newFrame.origin.x < 0)
newFrame.origin.x = 0;
if(newFrame.origin.y < 0)
newFrame.origin.y = 0;
if(newFrame.origin.x + newFrame.size.width > self.frame.size.width)
newFrame.origin.x = self.frame.size.width - self.imageView.frame.size.width;
if(newFrame.origin.y + newFrame.size.height > self.frame.size.height)
newFrame.origin.y = self.frame.size.height - self.imageView.frame.size.height;
self.imageView.frame = newFrame;
}
}
a) You can set the clipsToBounds property of your UIView to YES
b) You can use the fallowing code for moving your UIImageView
self.imageView.center = CGPointMake(MAX(0.0, MIN(location.x - previousLocation.x, self.sub_View.bounds.size.width)), MAX(0.0, MIN(location.y - previousLocation.y, self.sub_View.bounds.size.height)));

Problems making an Image Gallery using ImageView's and touchesBegan

I'm trying to create an image gallery for my iPhone app. I have laid out the imageViews and I want them to increase in size when the user clicks on them, and then return to normal when they release. The code I have made works for the first image, but the rest are totally unresponsive. Even if I remove the first one completely.
Here is the code I have been trying to use, does anyone have any ideas as to why it might not be working?
Thanks!
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch view] == _imageOne)
{
CGRect newFrame = _imageOne.frame;
newFrame.size.width += 280;
newFrame.size.height += 280;
_imageOne.frame = newFrame;
}
if ([touch view] == _imageTwo)
{
CGRect newFrame2 = _imageTwo.frame;
newFrame2.size.width += 280;
newFrame2.size.height += 280;
_imageTwo.frame = newFrame2;
}
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch view] == _imageOne)
{
CGRect newFrame = _imageOne.frame;
newFrame.size.width -= 280;
newFrame.size.height -= 280;
_imageOne.frame = newFrame;
}
if ([touch view] == _imageTwo)
{
CGRect newFrame2 = _imageTwo.frame;
newFrame2.size.width -= 280;
newFrame2.size.height -= 280;
_imageTwo.frame = newFrame2;
}
}

UILabel does not register touch

I have a problem, I want to drag a label with finger, and I can't even register a touch on it. What can be a problem? self is my viewcontroller and self.label is my label.
EDIT:
My label is made programmatically over an uiimageview. UserInteractionEnables is set to YES.
I am not sure what is wrong, here is code in its entirety:
Init:
UIImage *myImage = [UIImage imageNamed:#"fish.jpg"];
UIImageView *mainImageView = [[UIImageView alloc] initWithImage:myImage];
self.view.frame = CGRectMake(0, 0, 320, 480);
self.view = mainImageView;
self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
self.label.userInteractionEnabled = YES;
self.label.text = #"Hello, World";
[self.view addSubview:self.label];
Dragging:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches]anyObject];
if([[touch view] isEqual:self.label])
{
NSLog(#"touch on label");
self.startLocation = [[touches anyObject] locationInView:self.label];
// startLocation is a CGPoint declare globaly in .h..and lblName is your UILabel
}
}
- (void) touchesMoved:(NSSet *)touches withEvent: (UIEvent *)event
{
UITouch *touch = [[event allTouches]anyObject];
if([touch view] == self.label)
{
CGPoint pt = [[touches anyObject] previousLocationInView:self.label];
CGFloat dx = pt.x - self.startLocation.x;
CGFloat dy = pt.y - self.startLocation.y;
CGPoint newCenter = CGPointMake(self.label.center.x + dx, self.label.center.y + dy);
self.label.center = newCenter;
}
}
EDIT 2:
I have also tried this code, but it doesn't work too. I think the problem is not in these methods but with registering touches.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.startLocation = [[touches anyObject] locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint point = [[touches anyObject] locationInView:self.label];
self.label.center = CGPointMake(self.label.center.x + point.x - self.startLocation.x, self.label.center.y + point.y - self.startLocation.y);
}
Make sure you check "User Interaction Enabled" on the label in interface builder, or if you you doing it in code, userInteractionEnabled=YES
By default, UILAbel does not respond to touches. You need to enable the userInteractionEnabled property.
label.userInteractionEnabled = YES;

UITextView text space go smaller during rezise

I'd like to enable the user to resize an UITextView. I display a button in the bottom rigth corner of the UITextView such as when the user moves it, the UITextView follow it and is resized.
This is works fine but the text space has a strange behaviour. The text space seems to get smaller and smaller during the resize. So if I resize a lot, go to a big frame and then to a small frame, the text space has become smaller than the frame.
- (id) init{//My subclass of UITextView
self = [super init];
if(self){
//Resize button
//Init ResizeButton
self.resizeButton = [[UIButton alloc]init];
//Image
[self.resizeButton setImageForAllState:[UIImage imageNamed:#"Isosceles-right-triangle.png"]];
//Target
[self.resizeButton addTarget:self action:#selector(wasDragged:withEvent:) forControlEvents:UIControlEventTouchDragInside];
[self.resizeButton addTarget:self action:#selector(wasDragged:withEvent:) forControlEvents:UIControlEventTouchDragOutside];
//Add to view
[self addSubview:resizeButton];
//Self
//text font
[self setFont:[UIFont fontWithName:#"papyrus" size:17]];
}
return self;
}
- (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event
{
// NSLog(#"wasDragged");// get the touch
UITouch *touch = [[event touchesForView:button] anyObject];
// get delta
CGPoint previousLocation = [touch previousLocationInView:button];
CGPoint location = [touch locationInView:button];
CGFloat delta_x = location.x - previousLocation.x;
CGFloat delta_y = location.y - previousLocation.y;
// move button
button.center = CGPointMake(button.center.x + delta_x,
button.center.y + delta_y);
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width+ delta_x, self.frame.size.height+ delta_y);
}
The view is also draggable
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// Calculate offset
CGPoint pt = [[touches anyObject] locationInView:self];
float dx = pt.x - startLocation.x;
float dy = pt.y - startLocation.y;
CGPoint newcenter = CGPointMake(self.center.x + dx, self.center.y + dy);
// Set new location
self.center = newcenter;
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// Calculate and store offset, and pop view into front if needed
CGPoint pt = [[touches anyObject] locationInView:self];
startLocation = pt;
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
}
EDIT
Before resizing
Resizing
Back to original size
Well, I have this problem too. The soliution is to subclass UITextView and override setFrame: method. Before setting your wanted frame, set CGRectZero frame for textView. It will fix your problem. Code bellow.
- (void)setFrame:(CGRect)frame
{
[super setFrame:CGRectZero];
[super setFrame:frame];
}
Seems like you could do one of two things:
First: turn off the 'Adjust to fit' of the control
textfield.adjustsFontSizeToFitWidth = NO;
Second: Hardcode a font size into the code
textfield.font = [UIFont fontWithName:#"desired font name" size:10];

Programmatically added subview doesn't interact with other views, but xib-added view worked fine

harlanhaskins wrote:
I have a view called userSlider programmaticaly added in viewDidLoad:
self.userSlider = [[UserSliderView alloc] initWithFrame:CGRectMake(0, -120, 320, 155)];
[self.userSlider setUser:user];
[self.userSlider configureView];
[self.view addSubview:self.userSlider];
And a tableview called gameTableView.
I originally had added the userSlider into the xib as a custom view (because UserSlider has its own xib), and when I implemented these touch methods:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = (UITouch*)[touches anyObject];
start = [touch locationInView:self.view].y;
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if(start < 0)
{
return;
}
UITouch *touch = (UITouch *)[touches anyObject];
CGFloat now = [touch locationInView:self.view].y;
CGFloat diff = now - start;
sliderDirectionIsUp = diff < 0; //sliderDirectionIsUp is a BOOL
if ((self.userSlider.frame.origin.y == 0) && ((now < 120) || (now > 155))) {
return;
}
float newCenterY = self.userSlider.center.y + diff;
if (newCenterY < roundf(self.userSlider.frame.size.height / 2)) {
self.userSlider.center = CGPointMake(self.userSlider.center.x, newCenterY);
CGRect tableViewFrame = self.gameTableView.frame;
tableViewFrame.origin.y += diff;
tableViewFrame.size.height -= diff;
[self.gameTableView setFrame:tableViewFrame];
}
start = now;
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
CGRect tableViewFrame = self.gameTableView.frame;
if (sliderDirectionIsUp)
{
tableViewFrame.origin.y = 28;
tableViewFrame.size.height = (self.view.frame.size.height - tableViewFrame.origin.y);
//animate userSlider out of visible area
[UIView animateWithDuration:.3 animations:^{
self.userSlider.center = CGPointMake(self.userSlider.center.x, -roundf(self.userSlider.bounds.size.height/2.) + 35);
[self.gameTableView setFrame:tableViewFrame];
}];
}
else if(start >= 0)
{
tableViewFrame.origin.y = (self.userSlider.frame.size.height - 7);
tableViewFrame.size.height = (self.view.frame.size.height - tableViewFrame.origin.y);
//animate userSlider with top to mainviews top
[UIView animateWithDuration:.3 animations:^{
self.userSlider.center = CGPointMake(self.userSlider.center.x, roundf(self.userSlider.bounds.size.height/2.) - 0.5);
[self.gameTableView setFrame:tableViewFrame];
}];
}
}
then both views would move how I wanted them to.
But now when I add it programmatically, suddenly the tableView doesn't change unless I tap inside the area after moving it. It's really weird.
Any ideas?
If your userSlider`s frame is
CGRectMake(0, -120, 320, 155)
I doubt whether your userSlider can receive the sender event .Because if a UIControl`s frame be out of the superView , it may not receive the sender event(the outside part) . You can set the frame
CGRectMake(0, 0, 320, 155)
to have a try .

Resources