target action

//自定义target:
action:方法

#warning第一步声明target和action属性@property(nonatomic,assign)idmyTarget;
@property(nonatomic,assign)SELmyAction;

#warning第二部声明方法-(void)addmyTarget:(id)target
Ation:(SEL)action;

#warning第三步实现方法
-(void)addmyTarget:(id)target
Ation:(SEL)action{

#warning第四步接收传进来的目标对象和行为方法
self.myTarget= target;
self.myAction= action;

}

#warning第五步使用目标对象去执行行为方法
-(void)touchesBegan:(NSSet)touches withEvent:(UIEvent)event
{

[self.myTargetperformSelector:self.myActionwithObject:nil];}

不规则瀑布流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@protocol WaterLayoutDelegate <NSObject>

@required
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath;




@end
@interface WJY_WaterFallLayout : UICollectionViewLayout
@property (nonatomic, assign) id<WaterLayoutDelegate> delegate;
// 行数
@property (nonatomic, assign) NSInteger lineCount;
// 水平间距
@property (nonatomic, assign) CGFloat verticalSpacing;
// 垂直间距
@property (nonatomic, assign) CGFloat horizontalSpacing;
@property (nonatomic, assign) UIEdgeInsets sectionInset;
@end
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#import "WJY_WaterFallLayout.h"

@interface WJY_WaterFallLayout()
@property (nonatomic, retain) NSMutableArray *heights;
@property (nonatomic, retain) NSMutableArray *originX;
@property (nonatomic, retain) NSMutableDictionary *itemsArrange;

@property (nonatomic, retain) NSMutableDictionary *itemsInitialArrange;

@end
@implementation WJY_WaterFallLayout
#pragma mark - 重写,应 始终调用子类
- (void)prepareLayout
{
// 如果item 是0 返回
NSInteger cellCount = [self.collectionView numberOfItemsInSection:0];
if (cellCount == 0) {
return ;
}
// 调转系统的协议方法 并设置代理
self.delegate = (id<WaterLayoutDelegate>)self.collectionView.delegate;

self.itemsArrange = [NSMutableDictionary dictionary];
self.itemsInitialArrange = [NSMutableDictionary dictionary];

[self initAllarrays];

for (NSInteger i = 0; i < cellCount; i++) {
[
self layoutForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
}

}
#pragma 初始化所以数组
- (void)initAllarrays
{

self.heights = [NSMutableArray array];
self.originX = [NSMutableArray array];
// item宽度
CGFloat itemWidth = ([UIScreen mainScreen].bounds.size.width - self.sectionInset.left - self.sectionInset.right - (self.lineCount - 1) * self.horizontalSpacing) / self.lineCount;

for (NSInteger i = 0; i < self.lineCount; i++) {

// 循环添加 每行的每个top的点到 height数组中
[self.heights addObject:[NSNumber numberWithDouble:self.sectionInset.top]];

//设置oringin_x 为0
CGFloat oringin_x = 0.0;

if (i == 0) {
//i = 0 x点 = left;
oringin_x = self.sectionInset.left;
} else {
// x = i + item宽 + 横向宽度
oringin_x = [self.originX[i - 1] doubleValue] + itemWidth + self.horizontalSpacing;
}
// 把得到的点加到 x数组中
[self.originX addObject:[NSNumber numberWithDouble: oringin_x]];
}

}
#pragma mark - itme设置
- (void)layoutForItemAtIndexPath:(NSIndexPath *)indexPath
{

CGRect rect = CGRectZero;
// 协议方法
CGSize size = [self.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];

rect.size.height = size.height;

rect.size.width = ([UIScreen mainScreen].bounds.size.width - self.sectionInset.left - self.sectionInset.right - (self.lineCount - 1) * self.horizontalSpacing) / self.lineCount;

NSInteger index = [self getLowerHeightRowIndex:self.heights];

rect.origin.x = [self.originX[index] doubleValue];
rect.origin.y = [self.heights[index] doubleValue];

CGFloat newHeight = rect.origin.y + rect.size.height + self.verticalSpacing;

[self.heights replaceObjectAtIndex:index withObject:[NSNumber numberWithDouble: newHeight]];

[self.itemsArrange setObject:indexPath forKey:NSStringFromCGRect(rect)];

[self.itemsInitialArrange setObject:indexPath forKey:NSStringFromCGRect(CGRectMake(rect.origin.x, rect.origin.y - [UIScreen mainScreen].bounds.size.height, rect.size.width, rect.size.height))];
}
#pragma mark - 子类必须重写此方法并使用它来返回的宽度和高度的视图的内容。这些值表示的宽度和高度的所有内容,视图使用此信息来配置其自身内容的大小,以便滚动。
- (CGSize)collectionViewContentSize
{


CGFloat heightest = [self getHeightest:self.heights];

CGSize size = CGSizeMake(0, heightest);

return size;
}
#pragma mark - 设置布局信息
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {

UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

NSArray *keyArr = self.itemsArrange.allKeys;

for (NSString *rectStr in keyArr) {

if (self.itemsArrange[rectStr] != indexPath) {
continue;
}

CGRect rect = CGRectFromString(rectStr);

attributes.frame = rect;

break;

}

return attributes;
}
#pragma mark - 重新自定义layout
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath {
// layout初始化方法
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:itemIndexPath];

NSArray *keyArr = self.itemsArrange.allKeys;

for (NSString *rectStr in keyArr) {
// item的rect信息和布局信息不等 就跳出本次循环
if (self.itemsInitialArrange[rectStr] != itemIndexPath) {
continue;
}

CGRect rect = CGRectFromString(rectStr);

attributes.frame = rect;

break;

}

return attributes;
}

#pragma mark - 布局属性返回数组 视图在给定矩形
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {

CGFloat up = rect.origin.y;

CGFloat down = rect.origin.y + rect.size.height;

NSMutableArray *attributes = [NSMutableArray array];

for (NSString *rectStr in self.itemsArrange) {

CGRect itemRect = CGRectFromString(rectStr);

if (itemRect.origin.y <= down && itemRect.origin.y + itemRect.size.height >= up) {

NSIndexPath *indexPath = [self.itemsArrange objectForKey:rectStr];

//设置布局信息 添加到数组里
[attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
}
}

return attributes;
}
# pragma mark - 获取低行高
- (NSInteger)getLowerHeightRowIndex:(NSMutableArray *)height {

if (height.count == 0) {
return 0;
}

NSInteger index = 0;

CGFloat heightest = [height[0] doubleValue];

for (NSInteger i = 1; i < height.count; i++) {
// 判定获取低行位置
index = heightest > [height[i] doubleValue] ? i : index;
}

return index;
}
# pragma mark - 获取高度
- (CGFloat)getHeightest:(NSMutableArray *)height {

if (height.count == 0) {
return 0;
}

CGFloat heightest = self.sectionInset.top;
// 遍历最高点
for (NSInteger i = 0; i < height.count; i++) {
// 如果heightest为最高点返回返回 如果不是则返回height
heightest = heightest > [height[i] doubleValue] ? heightest : [height[i] doubleValue];
}

return heightest;
}


@end

协议

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
协议共分六步:1.声明协议2.声明代理人属性3.执行协议方法4.签订协议5.指定代理人6.实现协议方法/******************声明协议的类****************************/

/******************声明协议的类.h****************************/#warning协议第一步声明协议@protocolMarry <NSObject>
-(void)makeMoney:(NSString*)text;

@end

#warning协议第二步声明代理人@interfaceGirl :NSObject@property(nonatomic,assign)id<Marry>myDelegate;//assign弱引用,不会对内存引起记数变化
-(void)getMessage:(NSString*)content;@end/*********************************************************/


/******************声明协议的类.m****************************/#warning协议第三步执行协议方法@implementationGirl-(void)getMessage:(NSString*)content
{

   NSLog(@"%@",content);
   //使用代理人去执行协议方法
    [self.myDelegate makeMoney:@"赶快去赚钱!!!"];
   
}@end/******************************************************/


/********************执行协议的类*************************/

/********************执行协议的类.h***********************/#warning协议第四步签订协议#import"Girl.h"@interfaceBoy :NSObject<Marry>
-(void)sendMessageToGirl:(NSString *)content;@end/*******************************************************/
/********************执行协议的类.m*************************/#warning协议第五步指定代理人@implementationBoy
-(void)sendMessageToGirl:(NSString*)content
{

   Girl*aGirl = [[Girlalloc]init];


   //指定代理人,一定要找到声明协议类的对象,因为代理人是Girl的一个属性,所以用Girl对象调用属性.
    aGirl.myDelegate=self;//成为奴隶
    [aGirlgetMessage:content];
}

#warning协议第六步实现协议方法
-(void)makeMoney:(NSString*)text
{
   NSLog(@"%@",text);
}@end/******************************************************/

单例模式

单例模式:传值
单一的实例 唯一的对象 全工程中唯一的一个对象
作用是通过单例来保存工程中的多个页面中共享的对象和数据
生命周期和程序的生命周期一样 当程序结束时单例对象释放掉

category extension

category和extension用来做类扩展的,可以对现有类扩展功能或者修改其功能。在iOS中category应用是非常广泛的,系统自带的很多类都有多个category扩展功能。
一般category中可以定义新的方法、重写类原来的方法和添加readonly属性
而extension可以认为是匿名的category,但是这个extension相对于category有有一个特殊功能:在extension中可以定义可写的属性,公有可读、私有可写的属性(Publicly-Readable, Privately-Writeable Properties)一般这样实现!
举例说明如下:1. 创建测试程序empty application2. 我们自定义一个UIViewController,命名为RootViewController,它的.h文件为:###[代码]c#/cpp/oc代码:
01`//02//
RootViewController.h03//
Test404//05//
Created by Vincent on 13-5-29.06//
Copyright (c) 2013年 DevDiv Community. All rights reserved.07//08` `09#import
<UIKit/UIKit.h>10` `11@interface` `RootViewController : UIViewController12@end`

那么在其对应的.m中会自动生成以下代码:###[代码]c#/cpp/oc代码:
01`//02//
RootViewController.m03//
Test404//05//
Created by Vincent on 13-5-29.06//
Copyright (c) 2013年 DevDiv Community. All rights reserved.07//08` `09#import
“RootViewController.h”10` `11@interface` `RootViewController ()12@end1314@implementation RootViewController151617- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil18{19self
= [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];20 if` `(self) {21//
Custom initialization22 }23returnself;24}25` `26-
(void)viewDidLoad27{28 [super viewDidLoad];29//
Do any additional setup after loading the view.30 self.title =@”RootController”;31self.navigationItem32}33` `34-
(void)didReceiveMemoryWarning35{36 [super didReceiveMemoryWarning];37//
Dispose of any resources that can be recreated.38}39` `40@end`

  1. 第2步中我们能看到###[代码]c#/cpp/oc代码:
    1`@interface` `RootViewController ()2@end`
    这个就是extension了(也就是特殊类型的category)
    如果我们在.h添加这样一个属性@property (readonly) float value;那么RootViewController对外就暴露一个readonly的属性,它是公开的,所以外部是不能够对它进行写操作的。这时我们可以在extension加入以下代码:@property (readwrite) float value;那么这个属性在内部就是可读写的了,如果是只读只能在构造时期对它赋值,其他类方法中是不能对其赋值的。有了这个特性支持,那么类的内部方法均可以对其进行赋值了。

和CFStringRef相关的CFSTR与和NSString相关的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CoreFoundation里面的CFStringRefNSString*是可以直接转换的,两种也都有一个相似的用来直接赋常量的操作。例如:

CFStringRef a = CFSTR("a");
NSString *b = @"b";

CFSTR是一个宏,这个宏的定义可能是CFStringMakeConstantString,也可能是__builtin___CFStringMakeConstantString。如果是CFStringMakeConstantString,看看CFStringMakeConstantString的实现就会明白,CFSTR("a")是存放在一个全局字典里面的,下次用到CFSTR("a")的时候先查字典里面有没有,如果有就是用存在的,如果没有则分配一个,并且放到字典里面。

所以这里有两个需要注意的,一:CFSTR分配出来的字符串对象是不能自己释放的,如果你释放了下次在使用就会使用到一个野对象;二:多线程使用可能会出问题,因为全局的字典是没有锁的。

NSString的@有些不一样,应该和__builtin___CFStringMakeConstantString有些类似,允许你多线程使用,同样也不需要你自己去release,可以理解为b是一个autorelease的对象,系统会自己自动收回b。如果想长时间持有b那就retain,但不要忘了release。

他们俩直接类型转换就可以了,比如
CFStringRef aCFString = (CFStringRef)aNSString;
NSString *aNSString = (NSString *)aCFString;

夜间模式

夜间模式:利用继承与NSUserDefaults1.创建基类,负责夜间模式的转换2.所有的类都继承于基类,基类的模式改变了,所有子类的模式也改变了3.夜间模式触发的按钮发送通知4.利用NSUserDefault把模式保存到本地

屏幕横屏竖屏转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//横屏
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIInterfaceOrientationLandscapeRight;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}

//竖屏
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIInterfaceOrientationPortrait;
[invocation setArgument:&val atIndex:2];
[invocation invoke];


}
|