工作需要,最近在进行iOS方面的图表工作。找了很多第三方库都无法实现效果,所以决定自己写一个控件。

《iOS 自定义控件开发(上)》

《iOS 自定义控件开发(中)》

#0 目标

希望可以写一个通用的图表控件(仅针对此项目),虽然开发难度增大,但是可以学习到很多知识。并且控件使用简单,可以自适应大小,支持屏幕旋转。

#1 准备工作

  • 网上各种查资料
  • 研究了一下系统自带控件,全部基于UIView
  • 开发过程中使用storyboard,在页面中加入一个View来控制大小,自定义控件放入此view中并且填充满,让程序可以自适应屏幕尺寸。

#2 开始自定义

创建自定义控件,继承自UIView。

//
// LGChartView.h
//
// 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
//
// Created by Luna Gao on 15/10/29.
// Copyright © 2015年 All rights reserved.
// #import "LGChartView.h" @implementation LGChartView UIView *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创建一个ViewController,在其中放入一个UIView,这个UIView决定了自定义控件在界面中的显示位置和大小,并在其相关联的ChartViewController中获取。至此,storyboard的工作完成。

//
// ChartViewController.h
//
// Created by Luna Gao on 15/10/29.
// Copyright © 2015年 All rights reserved.
// #import <UIKit/UIKit.h>
#import "LGChartView.h" @interface ChartViewController : 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 其他

如有问题,或不正确的地方,或有更好的实现方法,请不要吝啬,在下面留言吧···么么哒···

iOS 自定义控件开发(上)的更多相关文章

  1. iOS 自定义控件开发(中)

    <iOS 自定义控件开发(上)> <iOS 自定义控件开发(中)> 接上篇iOS自定义控件开发之后,我们尝试另外一种. 在Xcode的右边,会看到如下的图 其中,上面有一个:C ...

  2. iOS自定义控件开发详解

    http://blog.csdn.net/zhangao0086/article/details/45622875

  3. iOS视频流开发(2)—视频播放

    承上篇,本篇文章主要介绍iOS视频播放需要用到的类.以及他们的使用场景和开发中遇到的问题. MPMoviePlayerViewController MP简介 iOS提供MPMoviePlayerCon ...

  4. iOS视频流开发(2) — 视频播放

    iOS视频流开发(2) — 视频播放  承上篇,本篇文章主要介绍iOS视频播放需要用到的类.以及他们的使用场景和开发中遇到的问题. MPMoviePlayerViewController MP简介 i ...

  5. Unity iOS混合开发界面切换思路

    Unity iOS混合开发界面切换思路 最近有很多博友QQ 私信 或则 留言联系我,请教iOS和Unity界面之前相互切换的问题,源代码就不私下发你们了,界面跳转功能的代码我直接贴到下面好了,顺带说i ...

  6. ios新手开发——toast提示和旋转图片加载框

    不知不觉自学ios已经四个月了,从OC语法到app开发,过程虽然枯燥无味,但是结果还是挺有成就感的,在此分享我的ios开发之路中的小小心得~废话不多说,先上我们今天要实现的效果图: 有过一点做APP经 ...

  7. iOS常用开发技巧

    iOS开发过程中,总有那么一些个小问题让人纠结,它们不会让程序崩溃,但是会让人崩溃.除此之外,还将分享一些细节现在我通过自己的总结以及从其他地方的引用,来总结一下一些常见小问题. 本篇长期更新,多积累 ...

  8. 【iOS 使用github上传代码】详解

    [iOS 使用github上传代码]详解 一.github创建新工程 二.直接添加文件 三.通过https 和 SSH 操作两种方式上传工程 3.1https 和 SSH 的区别: 3.1.1.前者可 ...

  9. iOS APP开发的小知识(分享)

          亿合科技小编发现从2007年第一款智能手机横空出世,由此开启了人们的移动智能时代.我们从一开始对APP的陌生,到现在的爱不释手,可见APP开发的出现对我们的生活改变有多巨大.而iOS AP ...

随机推荐

  1. C/S架构程序多种类服务器之间实现单点登录(转)

    (一) 在项目开发的过程中,经常会出现这样的情况:我们的产品包括很多,以QQ举例,如登陆.好友下载.群下载.网络硬盘.QQ游戏.QQ音乐等,总不能要求用户每次输入用户名.密码吧,为解决这个问题,高手提 ...

  2. hibernate一对一关系实现

    按照主键映射,按照外键映射 Address.hbm.xml: <?xml version="1.0"?><!DOCTYPE hibernate-mapping P ...

  3. CentOS下SSH无密码登录的配置

    1.确认本机sshd的配置文件(需要root权限) $ gedit /etc/ssh/sshd_config 找到以下内容,并去掉注释符"#" RSAAuthentication ...

  4. 本地数据下,radiobutton和图片组合,利用adapter+listview进行单选

    浮生偷得半日闲,等接口定义的过程中,重新复习下adapter+listview实现单选的方法 主界面 <RelativeLayout xmlns:android="http://sch ...

  5. Storm集群的安装与测试

    首先安装zookeeper集群,然后安装storm集群. 我使用的是centos 32bit的三台虚拟机. MachineName ip namenode 192.168.99.110 datanod ...

  6. 探索 OpenStack 之(11):cinder-api Service 启动过程分析 以及 WSGI / Paste deploy / Router 等介绍

    OpenStack 中的每一个提供 REST API Service 的组件,比如 cinder-api,nova-api 等,其实是一个 WSGI App,其主要功能是接受客户端发来的 HTTP R ...

  7. c++ static变量

    C++中Static作用和使用方法   1.什么是static?  static是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性. 2.为什么要引入static?   函数内部定义的变量, ...

  8. 自定义listview的步骤

    1.定义一个实体类: public class Fruit { private String name; private int imageId; public Fruit(String name, ...

  9. 【读书笔记《Android游戏编程之从零开始》】18.游戏开发基础(碰撞检测)

    1.矩形碰撞 所谓矩形碰撞,就是利用两个矩形之间的位置关系来进行判断,如果矩形的像素在另外一个矩形之中,或者之上都可以认为这两个矩形发生了碰撞. 如果单纯的去考虑哪些情况会判定两个矩形发生碰撞,倒不如 ...

  10. Python中的逗号有什么作用?

    最近研究python  遇到个逗号的问题 一直没弄明白 今天总算搞清楚了 1.逗号在参数传递中的使用: 这种情况不多说  没有什么不解的地方 就是形参或者实参传递的时候参数之间的逗号 例如def  a ...