iOS 自訂控制項開發,ios自訂控制項
工作需要,最近在進行iOS方面的圖表工作。找了很多第三方庫都無法實現效果,所以決定自己寫一個控制項。
#0 目標
希望可以寫一個通用的圖表控制項(僅針對此項目),雖然開發難度增大,但是可以學習到很多知識。並且控制項使用簡單,可以自適應大小,支援旋轉螢幕。
#1 準備工作
- 網上各種查資料
- 研究了一下系統內建控制項,全部基於UIView
- 開發過程中使用storyboard,在頁面中加入一個View來控制大小,自訂控制項放入此view中並且填充滿,讓程式可以自適應螢幕尺寸。
#2 開始自訂
建立自訂控制項,繼承自UIView。
//// LGChartView.h// feikangApp//// Created by Luna Gao on 15/10/29.// Copyright © 2015年 All rights reserved.//#import <UIKit/UIKit.h>@interface LGChartView : UIView - (instancetype)initWithParentView:(UIView*) view;@end
//// LGChartView.m// feikangApp//// Created by Luna Gao on 15/10/29.// Copyright © 2015年 All rights reserved.//#import "LGChartView.h"@implementation LGChartViewUIView *parentView;- (instancetype)initWithParentView:(UIView*) view { parentView = view; return [self init];}- (instancetype)init{ return [self initWithFrame: CGRectZero];}- (instancetype)initWithFrame:(CGRect)frame{ frame = CGRectMake(0, 0, parentView.frame.size.width, parentView.frame.size.height); self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor clearColor]; self.autoresizesSubviews = YES; self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; } return self;}-(void)layoutSubviews { [self setNeedsDisplay];}- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetRGBStrokeColor(context, 0.0f, 0.0f, 0.0f, 1);//線條顏色 CGContextMoveToPoint(context, CGRectGetMinX(self.frame), CGRectGetMaxY(self.frame) - 16); CGContextAddLineToPoint(context, CGRectGetMaxX(self.frame), CGRectGetMaxY(self.frame) - 16); CGContextStrokePath(context); CGContextSetLineWidth(context, 1.0);}@end
其中initWithParentView方法將父View傳入進來,通過父View的大小來確定我們自訂控制項的大小。我對於此處感覺有點怪怪的,雖然是我想到的解決方案···
其中
self.autoresizesSubviews = YES;self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
這兩句尤為重要,這兩句代碼保證了在頁面橫屏豎屏切換時,控制項會隨著螢幕中父View的大小改變而我們的自訂控制項跟著改變。
下面這個方法
-(void)layoutSubviews { [self setNeedsDisplay];}
保證了在頁面橫屏豎屏切換時,自訂控制項可以跟隨重新整理。
最後的drawRect方法,我將所有的繪製圖形的功能全部交給了它。
#3 在controller中引用
這一步已經非常的簡單了。
在storyboard中放入一個UIView,這個UIView決定了自訂控制項在介面中的顯示位置和大小,並在其相關聯的controller中擷取。至此,storyboard的工作完成。
//// TempDetailChartViewController.h// feikangApp//// Created by Luna Gao on 15/10/29.// Copyright © 2015年 All rights reserved.//#import <UIKit/UIKit.h>#import "LGChartView.h"@interface TempDetailChartViewController : UIViewController@property (weak, nonatomic) IBOutlet UIView *chartView;@end
下一步,在此controller中引用我們寫的自訂控制項,並且將自訂控制項的父類交給剛剛引用的UIView中。
- (void)viewDidLoad { [super viewDidLoad]; LGChartView *chartControl = [[LGChartView alloc] initWithParentView:self.chartView]; [self.chartView addSubview:chartControl];}
剩下的,就什麼都不用搞了···
直接跑項目看效果即可。至此,自訂控制項的demo就完成了,剩下的工作就是逐步完善自訂控制項,在其中加入委託等等等等。
#4 遇到的一些報錯和坑
1. 自訂控制項出現所繪製內容被展開,模糊等情況,請檢查是否在drawRect此方法中修改了自訂控制項的frame.size的大小,當然,也有可能是由於下面一條引起的。
2. 不要在自訂控制項中的drawRect中調用[self setNeedsDisplay]方法,之前出現了眾多奇奇葩葩的報錯和問題,就是因為調用了這玩意···重要的事情說3便
3. 不要在自訂控制項中的drawRect中調用[self setNeedsDisplay]方法,之前出現了眾多奇奇葩葩的報錯和問題,就是因為調用了這玩意···重要的事情說3便
4. 不要在自訂控制項中的drawRect中調用[self setNeedsDisplay]方法,之前出現了眾多奇奇葩葩的報錯和問題,就是因為調用了這玩意···重要的事情說3便
#5 其他
如有問題,或不正確的地方,或有更好的實現方法,請不要吝嗇,在下面留言吧···麼麼噠···