矩形区域的视图,可以在其中绘制自定义内容以及从用户触控手势,多点触控中获取手势
创建一个自定义视图,它有自己定义的手势
视图基本上是构造块,代表屏幕上的一块矩形区域,定义了一个坐标空间,在这个坐标系中,你可以进行绘制,可以在其中添加触控事件,掌握它们的位置
它是分级的,可以在视图中嵌套视图,每个视图只有一个父视图,可以有多个子视图,而这些子视图就是一个个矩形,相互之间可以重叠,不要求它们平铺
或者相互独立,特定视图的子视图是完全自由的,子视图的顺序很重要,因为它们可以是透明的
其实可以在矩形区域外绘图,Xcode中有一个开关,或者说是UIVew的一个属性,clip my subViews,不要让我的子视图超出边界,可以按照自己的意愿将
绘制内容控制在一定范围内,
1 创建自定义视图
UIView是所有绘制操作的核心
可以通过代码实现添加或移除view
- (void)addSubView:(UIView *)aView;- (void)removeFromSuperview;
self.view是UIViewController的顶级UIView
绘制或者处理触控事件时并不经常需要对其进行子类化,有时它们只是边界,只是用来定义一个坐标空间,
CGFloat CGSize CGPoint CGRect
绘制的单位都是点,而非像素点
CGRect bounds坐标系中绘制区域的原点以及宽度和高度,是你在自己视图中用自己的代码进行绘制时使用的矩形
CGRect frame指的是父视图坐标系中的一个矩形,完全包含了你的绘制区域,可以看到它是如何定位你的
center代表在父视图坐标系中所在位置的中心
视图可以旋转,包含它的矩形会变大
UIView中有一个方法叫作drawRect,你只要实现这个方法,就可以绘制自己想要的东西
很重要的一点,永远不要调用drawRect,它时由系统来调用,如果你想要重绘图,就调用setNeedDisplay,它会告诉系统,这个视图需要被重绘,系统会在合适的时间
调用drawRect
我如何实现自己的drawRect:?
方法是使用quartz库,叫作core graphics ,其中有很多C函数,也可以用UIBezierPath类,它可以将各种复杂形状放入一个大的路径,可以在屏幕上对其描边或者填充
Core Graphics的工作思路
你需要有一个可以绘制的context,你需要创建路径:三角形,正方形,或者任意形状,然后设置你想要的字体,颜色,线宽等,然后对刚才创建的路径进行描边或填充
UIBezierPath封装了上述全部操作,帮你处理好了context,创建路径的方法就是向UIBezierPath实例发送消息,它允许你设置线宽,颜色,然后调用它的方法进行描边和填充
通常情况下不用考虑context,context代表绘制的位置,对于一般绘制,UIKit会在调用drawRect前替你设置好了context,当执行drawRect后,context就可以使用了,
CGContextRef context = UIGraphicsGetCurrentContext();在drawRect中调用这个方法,你会得到一个cookie,将它作为第一个参数,传递给core graphics函数,这些CG函数并不经常使用,只有在UIbezierPath无法达到目标时
绘制一张扑克牌
1 拖入一个view,调整合适尺寸,然后为其写一个UIView的子类:aCardView
首先考虑这个类的public API :花色,数字,反正面
@property (nonatomic) NSUInteger rank;
@property (strong, nonatomic) NSString *suit;
@property (nonatomic) BOOL faceUp;
更改所有public API的setter
- (void)setSuit:(NSString *)suit
{
_suit = suit;
[self setNeedsDisplay];//如果有人修改类suit,我就要告诉系统去重绘
}
- (void)setRank:(NSUInteger)rank
{
_rank = rank;
[self setNeedsDisplay];
}
- (void)setFaceUp:(BOOL)faceUp
{
_faceUp = faceUp;
[self setNeedsDisplay];
}
开始绘制,用UIbezierPath来实现
#define CORNER_FONT_STANDARD_HEIGHT 180.0
#define CORNER_RADIUS 12.0
//实现任意bounds下的绘制
- (CGFloat)cornerScaleFactor { return self.bounds.size.height / CORNER_FONT_STANDARD_HEIGHT; }
- (CGFloat)cornerRadius { return CORNER_RADIUS * [self cornerScaleFactor]; }
- (CGFloat)cornerOffset { return [self cornerRadius] / 3.0; }
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:[self cornerRadius]];
[roundedRect addClip];//在roundedRect内绘图
[[UIColor whiteColor] setFill];
UIRectFill(self.bounds);//填充了这个矩形
[[UIColor blackColor] setStroke];
[roundedRect stroke];//在卡牌边缘加一圈黑色边框
}
设置背景和透明度
- (void)setup
{
self.backgroundColor = nil;//不设置背景
self.opaque = NO;//透明
self.contentMode = UIViewContentModeRedraw;//bound变化了,调用drawRect
}
在awakeFromNib中执行它,因为在这个demo中,我要从storyboard中创建它
- (void)awakeFromNib
{
[self setup];
}
下面是绘制牌角
用NSAttributedString,将这个左上角的字符串设置成 A 回车 梅花,然后放在左上角
在属性化字符串中有两项需要设置,一个是字体,这里用预设字体,二是需要将段落样式设为居中,让A 和梅花上下对齐居中,
- (NSString *)rankAsString
{
return @[@"?", @"A", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"J", @"Q", @"K"][self.rank];
}
- (void)drawCorners
{
NSMutableParagraphStyle *paragraphStyle= [[NSMutableParagraphStyle alloc]init];
paragraphStyle.alignment = NSTextAlignmentCenter;//设置居中格式
UIFont *cornerFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
cornerFont = [cornerFont fontWithSize:cornerFont.pointSize * [self cornerScaleFactor]];//字体大小随屏幕改变
NSAttributedString *cornerText = [[NSAttributedString alloc]initWithString:[NSString stringWithFormat:@"%@\n%@", [self rankAsString], self.suit] attributes:@{NSFontAttributeName:cornerFont, NSParagraphStyleAttributeName:paragraphStyle}];
CGRect textBounds;
textBounds.origin = CGPointMake([self cornerOffset], [self cornerOffset]);
textBounds.size = cornerText.size;
[cornerText drawInRect:textBounds];//在textBounds中绘制cornerText
}
在storyboard中设置outlet
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.aCardView.rank = 13;
self.aCardView.suit = @"♥️";
}
然后将左上角的cornerText上下颠倒,然后放在右下角
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, self.bounds.size.width, self.bounds.size.height);
CGContextRotateCTM(context, M_PI);
[cornerText drawInRect:textBounds];
下一步绘制牌面
UIImage *faceImage = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@",[self rankAsString], self.suit]];
if(faceImage){
CGRect imageRect = CGRectInset(self.bounds, self.bounds.size.width * 0.1, self.bounds.size.height * 0.1);//缩放
[faceImage drawInRect:imageRect];
} else{
[self drawPips];
}

被折叠的 条评论
为什么被折叠?



