如果要VIEW支持用户交互,得要设置
self.userInteractionEnabled = YES;
一个简单的UIView例子
@interface DragView : UIImageView
{
CGPoint startLocation;
}
@end
@implementation DragView
- (id) initWithImage: (UIImage *) anImage
{
if (self = [super initWithImage:anImage])
self.userInteractionEnabled = YES;
return self;
}
- (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;
[[self superview] bringSubviewToFront:self];
NSLog(@"begin");
}
- (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);
// Bound movement into parent bounds
float halfx = CGRectGetMidX(self.bounds);
newcenter.x = MAX(halfx, newcenter.x);
newcenter.x = MIN(self.superview.bounds.size.width - halfx, newcenter.x);
float halfy = CGRectGetMidY(self.bounds);
newcenter.y = MAX(halfy, newcenter.y);
newcenter.y = MIN(self.superview.bounds.size.height - halfy, newcenter.y);
// Set new location
self.center = newcenter;
}
@end
手动创建一图片的UIImageView
- (UIImage *) createImage
{
UIColor *color = [UIColor colorWithRed:RANDLEVEL green:RANDLEVEL blue:RANDLEVEL alpha:1.0f];
//设置图片的区域
UIGraphicsBeginImageContext(CGSizeMake(SIDELENGTH, SIDELENGTH));
CGContextRef context = UIGraphicsGetCurrentContext();
// Create a filled ellipse 填充区域
[color setFill];
CGRect rect = CGRectMake(0.0f, 0.0f, SIDELENGTH, SIDELENGTH);
CGContextAddEllipseInRect(context, rect);
CGContextFillPath(context);
// Outline the circle a couple of times
CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);
CGContextAddEllipseInRect(context, CGRectInset(rect, INSET_AMT, INSET_AMT));
CGContextStrokePath(context);
CGContextAddEllipseInRect(context, CGRectInset(rect, 2*INSET_AMT, 2*INSET_AMT));
CGContextStrokePath(context);
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return theImage;
}
判断是否在区域里面 HALFSIDE是圆的半径
- (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint pt;
float HALFSIDE = SIDELENGTH / 2.0f;
// normalize with centered origin
pt.x = (point.x - HALFSIDE) / HALFSIDE;
pt.y = (point.y - HALFSIDE) / HALFSIDE;
// x^2 + y^2 = radius
float xsquared = pt.x * pt.x;
float ysquared = pt.y * pt.y;
// If the radius < 1, the point is within the clipped circle
if ((xsquared + ysquared) < 1.0) return YES;
return NO;
}
根据图像的像位判断是否点击到图片,位图上面的触摸
- (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
//如果点下去的点不在self.bounds里面直接返回NO
if (!CGRectContainsPoint(self.bounds, point)) {
return NO;
}
//如果这个点的中断值 ALPHA小于33%,就可以看做是透明了,但也要和实际情况
return (bytes[alphaOffset(point.x, point.y, self.image.size.width)] > 85);
}
//计算当前点在数像中的位的位置
//X,Y表示点的坐标,W表示当前VIEW的宽度
NSUInteger alphaOffset(NSUInteger x, NSUInteger y, NSUInteger w){
return y * w * 4 + x * 4 + 0;
}
//计算图像的位
unsigned char *getBitmapFromImage (UIImage *image)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL)
{
fprintf(stderr, "Error allocating color space\n");
return NULL;
}
CGSize size = image.size;
// void *bitmapData = malloc(size.width * size.height * 4);
unsigned char *bitmapData = calloc(size.width * size.height * 4, 1); // Courtesy of Dirk. Thanks!
if (bitmapData == NULL)
{
fprintf (stderr, "Error: Memory not allocated!");
CGColorSpaceRelease(colorSpace);
return NULL;
}
CGContextRef context = CGBitmapContextCreate (bitmapData, size.width, size.height, 8, size.width * 4, colorSpace, kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace );
if (context == NULL)
{
fprintf (stderr, "Error: Context not created!");
free (bitmapData);
return NULL;
}
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
CGContextDrawImage(context, rect, image.CGImage);
unsigned char *data = CGBitmapContextGetData(context);
CGContextRelease(context);
return data;
}
视图持久性和归档
//持久化
- (void) updateDefaults
{
NSMutableArray *colors = [[NSMutableArray alloc] init];
NSMutableArray *locs = [[NSMutableArray alloc] init];
for (DragView *dv in [[self.view viewWithTag:201] subviews])
{
[colors addObject:dv.whichFlower];
[locs addObject:NSStringFromCGRect(dv.frame)];
}
[[NSUserDefaults standardUserDefaults] setObject:colors forKey:@"colors"];
[[NSUserDefaults standardUserDefaults] setObject:locs forKey:@"locs"];
[[NSUserDefaults standardUserDefaults] synchronize];
[colors release];
[locs release];
}
//删除
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"colors"];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"locs"];
//加载
NSMutableArray *colors = [[NSUserDefaults standardUserDefaults] objectForKey:@"colors"];
NSMutableArray *locs = [[NSUserDefaults standardUserDefaults] objectForKey:@"locs"];
//归档
@interface DragView : UIImageView
{
CGPoint startLocation;
NSString *whichFlower;
}
@property (retain) NSString *whichFlower;
@end
@implementation DragView
@synthesize whichFlower;
//保存
- (void) encodeWithCoder: (NSCoder *)coder
{
[coder encodeCGRect:self.frame forKey:@"viewFrame"];
[coder encodeObject:self.whichFlower forKey:@"flowerType"];
}
//初始化
- (id) initWithCoder: (NSCoder *)coder
{
[super initWithFrame:CGRectZero];
self.frame = [coder decodeCGRectForKey:@"viewFrame"];
self.whichFlower = [coder decodeObjectForKey:@"flowerType"];
self.image = [UIImage imageNamed:self.whichFlower];
self.userInteractionEnabled = YES;
return self;
}
//保存
NSArray *flowers = [[self.view viewWithTag:201] subviews];
[NSKeyedArchiver archiveRootObject:flowers toFile:DATAPATH];
//加载
NSArray *flowers = [NSKeyedUnarchiver unarchiveObjectWithFile:DATAPATH];
使用NSUndoManager来执行Undo和reDo操作
// Initialize the undo manager for this application
self.undoManager = [[NSUndoManager alloc] init];
//设置UNDO次数
[self.undoManager setLevelsOfUndo:999];
//注册 在视图时同注册
[[self.undoManager prepareWithInvocationTarget:self] setPosition:self.center];
//然后是否正在undo
while ([self.undoManager isUndoing]);
// Don't show the undo button if the undo stack is empty
//是否能undo
if (!self.undoManager.canUndo)
self.navigationItem.leftBarButtonItem = nil;
else
self.navigationItem.leftBarButtonItem = BARBUTTON(@"Undo", @selector(undo));
//最后再处理undo
[self.undoManager undo];
预留
预留
预留
预留
预留
分享到:
相关推荐
【标题】:“touch手势与触摸” 【描述】:在移动设备和触摸屏技术日益普及的今天,理解并掌握“touch手势与触摸”是开发高效、用户友好的触控应用的关键。这篇博客文章(链接:...
三、手势与触摸事件的关系: 手势识别器是基于触摸事件的,它们监听触摸事件并根据预设的模式进行匹配。一旦匹配成功,就会触发相应的动作。手势识别器可以覆盖或补充触摸事件处理,提供更高级别的抽象。 总的来说...
在iOS应用开发中,手势(Gesture Recognizers)和触摸(Touch Events)是用户界面交互的核心组成部分,它们使得用户可以通过屏幕上的各种操作与应用程序进行互动。本资料“ios应用源码之手势和触摸 2018128”很可能...
这份"iOS应用源码——手势和触摸.zip"压缩包很可能包含了一系列关于如何在iOS应用程序中实现和处理手势与触摸事件的示例代码。通过深入理解和学习这些源码,开发者可以提升自己在这一领域的技能。 首先,我们要了解...
五、手势与触摸事件的关系 手势识别在触摸事件的基础上进行,手势识别器会监听并处理一系列触摸事件。开发者可以根据需求选择使用手势识别器还是直接处理触摸事件。手势识别器提供了更高级的抽象,简化了某些常见...
在实际的设计过程中,这些手势部件可以帮助设计师准确地模拟用户在触摸屏设备上与应用或网页的交互方式。例如,通过拖动部件可以演示滑动浏览内容的效果,捏合手势则可以用来表示 pinch-to-zoom(缩小放大)功能,这...
为了提高性能,可能需要采用多线程处理,将计算密集型的手势识别工作与UI更新分开。 此外,为了提供更直观的反馈,可以使用Direct2D或GDI+来绘制触摸点和手势轨迹,这样用户可以实时看到他们的动作被系统识别的情况...
手势识别允许用户通过简单的触摸或滑动操作与应用程序进行交互,极大地提升了用户体验。以下是一些关于iOS手势的重要知识点: 1. **UIGestureRecognizer**: 这是iOS中的主要手势类,它提供了一个框架,用于识别并...
在移动设备上,用户通常通过触摸屏幕来与应用交互。Qt提供了一套完整的手势框架,用于识别和处理这些触摸事件,包括滑动(Swipe)、点击(Tap)、双击(Double Tap)、捏合(Pinch)、旋转(Rotate)等。这些手势...
9. **学习资源**:如"iphone的手势与触摸编程学习笔记"和"30天精通iPhone手机编程"等资料,可以帮助开发者深入理解iOS手势编程,提供实例教程和实践指导。 通过这些知识点的学习和实践,开发者能够构建出更加丰富和...
- **手势的取消与恢复**:合理处理手势的取消和恢复情况,例如在用户手指离开屏幕时取消手势,或在满足特定条件时恢复先前的操作。 - **自定义手势**:除了系统提供的手势外,还可以自定义手势,增加应用的独特性。 ...
在iOS开发中,手势(Gestures)和触摸(Touches)是用户与应用程序交互的核心机制。这个名为"手势和触摸"的源码压缩包很可能是为了帮助开发者深入了解并实践这两种技术。下面,我们将深入探讨iOS中的手势识别和触摸...
10. **手势与触摸事件的关系** `GestureDetector`是基于Android的触摸事件体系(`MotionEvent`)构建的。`MotionEvent`包含了触摸屏幕的所有信息,`GestureDetector`通过对`MotionEvent`的序列进行分析,识别出各种...
在实际应用中,手势识别器与触摸事件经常结合使用,为用户提供更丰富的交互体验。例如,在处理复杂的触摸序列时,可能需要同时监听触摸事件和手势识别器,以实现自定义的交互逻辑。在编写代码时,需要注意手势之间的...
在源码中,我们可以期待看到如何创建和配置这些手势识别器,并将它们与视图关联起来,以便在用户进行相应操作时调用相应的回调函数。这些回调函数通常会包含对用户行为的响应逻辑,如改变视图状态、更新数据或者执行...
在Android开发中,触摸屏手势是用户与应用程序交互的重要方式之一。本专题将深入探讨如何在Android平台上实现各种触摸手势,以提升应用的用户体验。通过实验代码,我们可以直观地理解这些手势的实现过程。 首先,...
4. **手势的注册与监听**:使用`QObject::connect()`将特定的手势信号连接到槽函数,或者通过覆盖`QWidget::gestureEvent()`方法来处理自定义手势。 5. **手势识别参数调整**:可以通过`QGesture::threshold()`和`...