详解iPhone SDK开发基础之自定义仪表控件

移动开发 iOS
控件使用两个UIView来实现仪表控件,并通过CGAffineTransform类来实现仪表指针的旋转,控件在UIDialView类中实现,来看本文如何定义UIDialView类的。

iPhone SDK开发基础之自定义仪表控件是本文要介绍的内容,主要是来学习仪表控件。在iOS开发中,因为程序的需要,有时要自行绘制iPhone SDK没有提供的界面控件,通常使用QuartzCore.framework即可画出你所需要的各种图形,在这里我们实现一个圆形的“仪表盘”控件,控件的外观如图3-48所示,用户可以通过旋转仪表控件的指针来设置程序需要的各种系统参数,如图所示:

详解iPhone SDK开发基础之自定义仪表控件

控件使用两个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 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

在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.autoresizesSubviewsYES;    
  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;  

  • 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.

在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;  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

在用户的旋转过程中通过设置指针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];  
 }  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

客户通过实现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];  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

小结:详解iPhone SDK开发基础之自定义仪表控件的内容介绍完了,希望通过本文的的学习能对你有所帮助!

责任编辑:zhaolei 来源: 博客园
相关推荐

2009-08-06 09:18:01

ASP.NET自定义控ASP.NET控件开发

2009-08-06 17:52:45

ASP.NET控件开发自定义控件

2011-08-02 11:17:13

iOS开发 View

2009-06-08 20:13:36

Eclipse自定义控

2011-07-18 14:39:53

iPhone SDK UIKit

2009-08-07 11:12:58

ASP.NET控件开发

2011-04-19 10:33:16

ASP.NET自定义控

2011-08-18 10:02:47

iPhone SDKOpenFlow

2011-08-18 09:52:13

iPhone SDKUIPageContr

2011-07-05 18:51:51

QT 控件 鼠标

2013-05-20 17:33:44

Android游戏开发自定义View

2021-08-16 14:45:38

鸿蒙HarmonyOS应用

2021-08-25 10:14:51

鸿蒙HarmonyOS应用

2011-08-11 11:51:07

iPhone键盘

2015-02-11 17:49:35

Android源码自定义控件

2009-07-31 10:23:09

ASP.NET源码DateTimePic

2021-09-06 14:58:23

鸿蒙HarmonyOS应用

2011-07-18 09:35:29

iPhone 框架

2009-07-28 09:32:41

ASP.NET自定义控

2017-02-17 09:37:12

Android自定义控件方法总结
点赞
收藏

51CTO技术栈公众号