当前位置:  编程技术>移动开发
本页文章导读:
    ▪不规则形态的uibutton        不规则形状的uibutton 有的时候,我们需要使用非规则形状的按钮。UIButton允许你选择带有alpha通道的图像。比如,我使用下面四个图像: 然后用Interface Builder创建用户定义按钮,你可以透过.........
    ▪ 容易的手势操作        简单的手势操作 头文件:   #define kMinimumGestureLength 25 #define kMaximumVariance 5 #import <UIKit/UIKit.h> @interface TouchesViewController : UIViewController { IBOutlet UILabel *label; CGPoint gestureStartPoint; } @end   .........
    ▪ Struts1和Struts2的差别和对比       Struts1和Struts2的区别和对比 Struts1和Struts2的区别和对比:Action 类: • Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。 • Struts 2 Action类可以实现一.........

[1]不规则形态的uibutton
    来源: 互联网  发布时间: 2014-02-18
不规则形状的uibutton

有的时候,我们需要使用非规则形状的按钮。UIButton允许你选择带有alpha通道的图像。比如,我使用下面四个图像:



然后用Interface Builder创建用户定义按钮,你可以透过图像的透明部分看到后面的按钮(假定按钮未定义为opaque)。.然而 UIButton 的点击测试(hit-testing)并未考虑图像的透明性,所以当你将图像重叠放置时,如图所示:



如果你点击此处:




默认的点击测试的结果是绿色菱形按钮被按下,而不是蓝色按钮。当然这可能就是你需要的效果,但大部分情况下并非如你所愿。那么怎样才能让你的程序正常工作?实际上很简单,你只需要一个UIButton的子类并重写点击测试方法。

 

然而,首先你需要一个方法能确定图像上指定点是透明的。遗憾的是UIImage无法像Cocoa为NSImage提供的 NSBitmapRepresentation 那样方便地访问位图数据。但是每个UIImage都具有一个称为CGImage的属性可以访问内部图像数据,Apple发布了一篇技术文章介绍了怎样通过CGImageRef访问内部位图数据 。


根据这篇文章的介绍,我们很容易就写出一个方法,它以CGPoint为参数,根据该点是否透明(0)与否返回YES或NO。


UIImage-Alpha.h

1
2
3
4
5
6
7
8
#import <UIKit/UIKit.h>

@interface UIImage( Alpha)

- ( NSData * ) ARGBData;
- ( BOOL ) isPointTransparent: ( CGPoint) point;

@end


UIImage-Alpha.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
CGContextRef CreateARGBBitmapContext ( CGImageRef inImage)
{
    CGContextRef    context = NULL ;
    CGColorSpaceRef colorSpace;
    void *          bitmapData;
    int             bitmapByteCount;
    int             bitmapBytesPerRow;

    size_t pixelsWide = CGImageGetWidth( inImage) ;
    size_t pixelsHigh = CGImageGetHeight( inImage) ;
    bitmapBytesPerRow   = ( pixelsWide * 4) ;
    bitmapByteCount     = ( bitmapBytesPerRow * pixelsHigh) ;

    colorSpace = CGColorSpaceCreateDeviceRGB( ) ;
    if ( colorSpace == NULL )
        return nil ;

    bitmapData = malloc ( bitmapByteCount ) ;
    if ( bitmapData == NULL )
    {
       CGColorSpaceRelease( colorSpace ) ;
       return nil ;
    }

    context = CGBitmapContextCreate ( bitmapData,
                                     pixelsWide,
                                     pixelsHigh,
                                     8,
                                     bitmapBytesPerRow,
                                     colorSpace,
                                     kCGImageAlphaPremultipliedFirst) ;

    if ( context == NULL )
    {
       free ( bitmapData) ;
       fprintf ( stderr , "Context not created!" ) ;
    }

    CGColorSpaceRelease( colorSpace ) ;

    return context;
}

@implementation UIImage( Alpha)

- ( NSData * ) ARGBData
{
    CGContextRef cgctx = CreateARGBBitmapContext( self.CGImage) ;
    if ( cgctx == NULL )        
        return nil ;

    size_t w = CGImageGetWidth( self.CGImage) ;
    size_t h = CGImageGetHeight( self.CGImage) ;
    CGRect rect = { { 0,0} ,{ w,h} } ;
    CGContextDrawImage( cgctx, rect, self.CGImage) ;

    void * data = CGBitmapContextGetData ( cgctx) ;
    CGContextRelease( cgctx) ;    

    if ( ! data)      
        return nil ;

    size_t dataSize = 4 * w * h; // ARGB = 4 8-bit components
    return [ NSData dataWithBytes: data length: dataSize] ;
}    

- ( BOOL ) isPointTransparent: ( CGPoint) point
{
    NSData * rawData = [ self ARGBData] ;  // See about caching this
    if ( rawData == nil )
       return NO ;

    size_t bpp = 4 ;
    size_t bpr = self.size.width * 4 ;

    NSUInteger index = point.x * bpp + ( point.y * bpr) ;
    char * rawDataBytes = ( char * ) [ rawData bytes] ;

    return rawDataBytes[ index] == 0 ;

}

@end

一旦我们有能力确定图像中的某点是否透明,我们就可以编写UIButton的子类,重写hitTest:withEvent: 方法。它将返回一个UIView的实例。如果该点在此视图或其子视图中未被点击,那么将返回nil。如果点击在其子视图,那么将返回点击中的子视图,如果 点击中视图,那么返回视图本身。


然而,我们可以进行一些简化,这是因为尽管UIButton继承了UIView,技术上可能具有子视图,但这非常的少见,而且Interface Builder并不支持这样做。所以在本文的实现中并不考虑子视图。


IrregularShapedButton.h

1
2
3
4
5
6
7
#import <UIKit/UIKit.h>

@interface IrregularShapedButton : UIButton {

}

@end

IrregularShapedButton.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#import "IrregularShapedButton.h"
#import "UIImage-Alpha.h"

@implementation IrregularShapedButton

- ( UIView * ) hitTest: ( CGPoint) point withEvent: ( UIEvent * ) event
{
    if ( ! CGRectContainsPoint( [ self bounds] , point) )
        return nil ;
    else
    {
        UIImage * displayedImage = [ self imageForState: [ self state] ] ;
        if ( displayedImage == nil ) // No image found, try for background image
        displayedImage = [ self backgroundImageForState: [ self state] ] ;
        if ( displayedImage == nil ) // No image could be found, fall back to
            return self;        

        BOOL isTransparent = [ displayedImage isPointTransparent: point] ;
        if ( isTransparent)
            return nil ;

    }

    return self;
}

@end
将Interface Builder中的四个图像按钮改为IrregularShapedButton,它们将正常工作了。
原文见:Irregularly Shaped UIButton

    
[2] 容易的手势操作
    来源: 互联网  发布时间: 2014-02-18
简单的手势操作

头文件:

 

#define kMinimumGestureLength  25
#define kMaximumVariance  5

#import <UIKit/UIKit.h>

@interface TouchesViewController : UIViewController {
	IBOutlet UILabel *label;
	CGPoint gestureStartPoint;
}

@end

 

实现文件:

 

#import "TouchesViewController.h"

@implementation TouchesViewController

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	UITouch *touch = [touches anyObject];
	gestureStartPoint = [touch locationInView:self.view];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
	UITouch *touch = [touches anyObject];
	CGPoint currentPosition = [touch locationInView:self.view];    
	
	CGFloat deltaX = fabsf(gestureStartPoint.x - currentPosition.x);
	CGFloat deltaY = fabsf(gestureStartPoint.y - currentPosition.y);
	
	if(deltaX >= kMinimumGestureLength && deltaY <= kMaximumVariance){
		label.text = @"Horizontal Swipe Detected";
		[self performSelector:@selector(eraseText) withObject:nil afterDelay:3];
	}
	else if(deltaY >= kMinimumGestureLength && deltaX <= kMaximumVariance){
		label.text = @"Vertical Swipe Detected";
		[self performSelector:@selector(eraseText) withObject:nil afterDelay:3];
	}
}

- (void)eraseText{
	label.text = @"";
}

- (void)dealloc {
	[super dealloc];
}

@end

 


    
[3] Struts1和Struts2的差别和对比
    来源: 互联网  发布时间: 2014-02-18
Struts1和Struts2的区别和对比
Struts1和Struts2的区别和对比:

Action 类:
• Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。
• Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去 实现 常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。

线程模式:
• Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
• Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)

Servlet 依赖:
• Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。
• Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。

可测性:
• 测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。
• Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。

捕获输入:
• Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经 常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存 在的JavaBean(仍然会导致有冗余的javabean)。
• Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。

表达式语言:
• Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
• Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--"Object Graph Notation Language" (OGNL).

绑定值到页面(view):
• Struts 1使用标准JSP机制把对象绑定到页面中来访问。
• Struts 2 使用 "ValueStack"技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。

类型转换:
• Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。
• Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。

校验:
• Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。
• Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性

Action执行的控制:
• Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。
• Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android中通过view方式获取当前Activity的屏幕截... iis7站长之家
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3