UIView创建不规则视图

No Comments

[申明]本文有点标题党,因为通过本文严格上讲并不能创建一个规则的UIView。
总所周知,UIView都是方形的,并不能产生一个不规则的形状的view(小弟才疏学浅,目前确实没有发现能够创建真实不规则视图的方法,如果有,不吝赐教,感激涕零!)。为什么我们有创建不规则view的需求?如果只是为了在View上显示不规则图形那大可不必,直接讲不规则图形添加到view上,然后讲view的backgroundColor设置为UIColor clearColor就可以;但是之所以有这样的需求,很大部分就是为了判断不规则的图形去响应触摸事件,判断图形是否被触摸选中了这样的要求,我们最直接的想法就是每个不规则图形都是一个view,那么图形是否选中就可以通过UIResponder的那一系列触摸有关的响应函数得知了,所以这个时候我们就需要不规则的view。但是显示的杯具是,iOS并没有提供这样的不规则view,如果要完成刚才的需求,就只能手动判断触摸的点是否在不规则图形里面了,这有的时候将是一件比较痛苦的事情。那么现在提供一种“创建不规则view”的解决方案:

不知道大家有没有注意到UIView有这样一个函数:- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 这个函数就是用来判断指定的点是否在View内,我们方法就是在这个函数中,如果point在指定的不规则图形内返回YES,反之就返回NO。这样不规则图形的bounds就相当于代表了view自己的bounds。这样当你触摸view的时候,当且只有当触摸到指定图形内才会使得view被触摸到,才会调用到UIResponder一系列触摸响应事件。

代码如下:

RoundView.h

1
2
3
4
5
6
7
@interface MyView : UIView {
  UIBezierPath *_path;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

@end

RoundView.m

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Print current selector's name
#define PRINT_CURRENT_SEL NSLog(@"<%@> %@", NSStringFromClass([self class]),NSStringFromSelector(_cmd))

//
// PrivateMethods
// This category provide private apis for RoundView class
//
@interface RoundView(PrivateMethods)

// Initialize all view's state
- (void)_init;

// Highlight view's border, better visual effect for testing.
- (void) _highlightBorder;

@end
@implementation RoundView(PrivateMethods)

- (void)_init{
  [self _highlightBorder];
  self.backgroundColor = [UIColor clearColor];

  // Create path object as round rect
  _path = [[UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds,  20, 20) cornerRadius:60] retain];
}

- (void) _highlightBorder{
  CALayer *theLayer = [self layer];
  theLayer.borderColor = [UIColor blueColor].CGColor;
  theLayer.borderWidth = 2;
}

@end

#pragma mark -

@implementation RoundView

- (id)initWithCoder:(NSCoder *)aDecoder{
  if((self = [super initWithCoder:aDecoder])){
    [self _init];
  }
  return self;
}

- (id)initWithFrame:(CGRect)frame {
  if ((self = [super initWithFrame:frame])) {
    [self _init];
  }
  return self;
}

- (void)drawRect:(CGRect)rect {
  [[UIColor redColor] setFill];
  [_path fill];
}

- (void)dealloc {
  [_path release];

  [super dealloc];
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
  return [_path containsPoint:point];
}

#pragma mark -
#pragma mark UIResponder touches

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
  PRINT_CURRENT_SEL;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
  PRINT_CURRENT_SEL;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
  PRINT_CURRENT_SEL;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
  PRINT_CURRENT_SEL;
}
@end

这个demo中用到了3.2以后提供的UIBezierPath类,来创建一个图形的path,在pointInside:withEvent:中判断点是不是在图形的里面,如果是返回YES,反之NO。这样就用找个图形的path代表了view的bounds。那么即使你触摸在view内但是没有在找个图形上,touchesBegan就不会被调用,不会打印相应信息在console中。
所以这样这个view的边界就变成了这个不规则图形的边界了,就变相地创建出了一个不规则的view了!cheers!

点击下载 源代码

如何给View添加背景图片

No Comments

给大家一个问题,如何给view添加背景图片?也许在你的脑中一下子会又N多方法,但是这里想介绍的是一种使用“内置”的方法,可以省去大家不少的代码。

UIView有这样一个属性

@property(nonatomic,copy)            UIColor          *backgroundColor;            // default is nil

以想到UIColor,可能大家都只是想到到UIColor只能设置纯色,但是UIColor就有很多神奇的地方!

+ (UIColor *)colorWithPatternImage:(UIImage *)image;

这个方法就可以产生一个基于图片的颜色,更加精确地说是Pattern,这样之后就可以用这个颜色/pattern来填充view背景了。其工作原理就是pattern的工作原理(详情见这里),所以如果是你的图片和view的大小一样的话,那么图片就不会重复绘制成tiled情况。

效果:

*但是针对UIScrollView极其Subclass(如UITableView)这样设置背景可能就和你想要的效果不一样了,因为这个方法实际是使用pattern最为paint color,所以在scroll的时候会将pattern重复绘制像是tiled一样。。。Oops…所以如果是对TableView设置背景,最简单的还是在tableview下面add一个含有背景图片的imageview,在将tableview的backgroundcolor设置为clear。

PS:UIColor还有几个很好玩的方法,读者可以自己尝试:

+ (UIColor *)lightTextColor

+ (UIColor *)darkTextColor

+ (UIColor *)groupTableViewBackgroundColor

+ (UIColor *)viewFlipsideBackgroundColor

PS2:

为什么将代码直接paste过来,wordpress竟然不支持xcode的语法颜色!!!求高人!

  • RSS
  • Twitter
  • Buzz
  • LinkedIn
  • Flickr