iPhone SDK開發基礎之自定義儀表控件是本文要介紹的內容,主要是來學習儀表控件。在iOS開發中,因爲程序的需要,有時要自行繪製iPhone SDK沒有提供的界面控件,通常使用QuartzCore.framework即可畫出你所需要的各種圖形,在這裏我們實現一個圓形的“儀表盤”控件,控件的外觀如圖3-48所示,用戶可以通過旋轉儀表控件的指針來設置程序需要的各種系統參數,如圖所示:
控件使用兩個UIView來實現儀表控件,並通過CGAffineTransform類來實現儀表指針的旋轉,控件在UIDialView類中實現,UIDialView類的定義如下。
// UIDialView.h
#import <UIKit/UIKit.h>
@protocol UIDialViewDelegate
@optional
- (void)dialValue:(int)tag Value:(float)value;
@end
@interface UIDialView : UIView {
id<UIDialViewDelegate> delegate;
NSTimer *timer;
UIImageView *iv;
float maxValue,minValue;
CGAffineTransform initialTransform ;
float currentValue;
}
@property(nonatomic,assign)id<UIDialViewDelegate>delegate;
@property CGAffineTransform initialTransform;
@property float currentValue;
@end
在UIDialView類的實現文件中,通過init()方法讀取圖片文件初始化控件背景和指針,代碼如下。
// UIDialView.m
#import "UIDialView.h"
@interface
UIDialView()
-(void)spin:(NSTimer *)timer;
-(float) goodDegrees:(float)degrees;
@end
#define degreesToRadians(degrees) (M_PI * degrees / 180.0)
#define radiansToDegrees(radians) (radians * 180 / M_PI)
static CGPoint delta;
static float deltaAngle;
static float currentAngle;
@implementation UIDialView
@synthesize initialTransform,currentValue;
- (void)dealloc {
[iv release];
[super dealloc];
}
@synthesize
delegate;
- (id)init{
if ((self = [super init])) {
self.userInteractionEnabled = YES;
iv =[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"knob. png"]];
UIImage *backgroundTile = [UIImage imageNamed: @"clock.png"];
UIColor *backgroundPattern = [[UIColor alloc] initWithPatternImage: backgroundTile];
self.contentMode = UIViewContentModeCenter;
[self setBackgroundColor:backgroundPattern];
[backgroundPattern release];
iv.backgroundColor = [UIColor clearColor];
iv.autoresizesSubviews= YES;
self.frame = CGRectMake(0, 0, iv.frame.size.width, iv.frame.size. height);
[self addSubview:iv];
[self bringSubviewToFront:iv];
[iv release];
currentValue = 0;
currentAngle = 0;
deltaAngle = 0.0;
}
return self;
}
在UIView的touchesBegan()方法中捕獲用戶Touch點的位置,並根據此位置使用atan2()函數計算出控件的初始化角度,代碼如下。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *thisTouch = [touches anyObject];
delta = [thisTouch locationInView:self];
float dx = delta.x - iv.center.x;
float dy = delta.y - iv.center.y;
deltaAngle = atan2(dy,dx);
initialTransform = iv.transform;
}
在用戶的旋轉過程中通過設置指針UIView對象的transform屬性實現儀表控件指針伴隨用戶手指的旋轉而旋轉,代碼如下。
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint pt = [touch locationInView:self];
float dx = pt.x - iv.center.x;
float dy = pt.y - iv.center.y;
float ang = atan2(dy,dx);
if (deltaAngle == 0.0) {
deltaAngle = ang;
initialTransform = iv.transform;
}else{
float angleDif = deltaAngle - ang;
CGAffineTransform newTrans = CGAffineTransformRotate(initialTransform, -angleDif);
iv.transform = newTrans;
float diffValue = [self goodDegrees:radiansToDegrees(angleDif)];
currentValue = maxValue - ((maxValue - minValue)/300)*diffValue;
if(currentValue > 100) currentValue = 100;
}
if (delegate != nil) {
[delegate dialValue:self.tag Value:currentValue];
}
}
客戶通過實現UIDialViewDelegate接口協議的dialValue()方法而得到控件的通知消息,代碼如下。
// DialViewController.h
#import <UIKit/UIKit.h>
#import "UIDialView.h"
@interface
DialViewController : UIViewController< UIDialViewDelegate> {
UIDialView *dialView;
UILabel *myLabel;
}
- (void)dialValue:(int)tag Value:(float)value{
NSString *str = [NSString stringWithFormat:@"%.1f",v*100];
[myLabel performSelector:@selector(setText:) withObject:str];
}
小結:詳解iPhone SDK開發基礎之自定義儀表控件的內容介紹完了,希望通過本文的的學習能對你有所幫助