0%

1 GitHub

博主已经写好了一份瀑布流的框架,如果你想直接使用,可以点击进入CFWaterFlowView的项目主页。

CFWaterFlowView是博主已经封装好的瀑布流框架,轻量级、简单、易用,希望你喜欢。

2 简介

瀑布流是一种非常常用的UI布局,可以为用户带来沉浸式的体验,不需要打断用户的阅读。非常适合带图片信息的展示。

CFWaterFlowView展示

瀑布流样式示例

阅读全文 »

其实几乎天天都在用block吧,却没有仔细研究过,这次也当给自己补课啦

block

这几个基本概念会帮助你理解block

  1. block是一种变量类型
  2. block是C级别的语法和运行机制
  3. block除了包含可执行代码以外,还包含了与堆、栈内存绑定的变量。所以Block对象包含着一组状态数据,这些数据在程序执行时用于对行为产生影响
  4. block的意义在于不仅包含了回调期间的代码,又包含了执行期间需要的数据,并且支持多线程
  5. block类似于C语言的函数指针,不要看的太难

block的定义和基本结构

放上@传智如意大师的解说图
block定义

现在看是不是有点麻烦?直接上例子,小鱼喜欢把详细的解释放在代码里(程序员风格),相信你一定瞬间弄懂

建立了一个command项目,列出了各种block的定义

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
int main(int argc, const char * argv[]) {
@autoreleasepool {

/********* 1.1 无参数无返回值-完整写法 *********/
void (^myBlock1)() = ^(){
NSLog(@"无参数无返回值的block");
};
myBlock1();




/********* 1.2 无参数无返回值-简写 *********/
void (^myBlock1_simple)() = ^{
NSLog(@"无参数无返回值的block的简写");
};
myBlock1_simple();




/********* 2.1 有参数无返回值 *********/
/**
* void (^block变量名)(参数类型及个数) = ^(形参列表){代码块};
*/
void (^myBlock2)(int, int) = ^(int x, int y){
NSLog(@"有参数无返回值,两数和为:%d", x + y);
};
myBlock2(1,2);




/********* 2.2 对block变量重新赋值 *********/
myBlock2 = ^(int x, int y) {
NSLog(@"对block变量重新赋值,两数差为:%d", x - y);
};
myBlock2(1,2);




/********* 3 无参数有返回值 *********/
NSString *(^myBlock3)() = ^ (){
return @"无参数有返回值";
};
NSLog(@"%@", myBlock3());




/********* 4 有参数有返回值 *********/
int (^myBlock4)(int, int) = ^(int x, int y) {
return x + y;
};

int result = myBlock4(1,2);
NSLog(@"有参数有返回值,两数和为:%d", result);





}
return 0;
}

阅读全文 »

项目经理的要求,给成员写一份简单的命名和编码规范,因为成员很多都是新人,甚至还有刚开始接触规范编码的,所以我就写了一份简单的。

还有很多不完善的地方,而且只是针对这次项目的,只是给一个参考。


XXXiOS项目-命名及编码规范

2015年11月3日星期二
Lotty周小鱼

<br/ >

1 类

1.1 遵守大驼峰命名法
1.2 Controller命名:
    1.1.1 ViewController子类命名规范:XXXController

ViewController子类命名规范

    1.1.2 TableViewController子类命名规范:XXXTableController
    1.1.3 其他Controller命名规范:与ViewController子类命名规范相同

1.1 View命名:
    1.1.1 View子类命名规范:XXXView
    1.1.2 View的Xib与相应的类同名

View的Xib与相应的类同名

<br/ >

2 协议

2.1 遵守大驼峰命名法
2.2 代理:
    2.2.1 代理写在相应类型的.h文件中,不需要单独建立文件
    2.2.2 命名规范:XXXDelegate,XXX和相应类名一致

代理命名规范

<br/ >

3 宏定义

3.1 避免在程序中直接出现常数,常数宏定义变量全部大写
3.2 使用超过一次的小段代码应以宏定义的形式来替代,遵循大驼峰命名法
3.3 常量的命名应当能够表达出它的用途

宏定义示例

<br/ >

4 枚举

4.1 遵循大驼峰命名法
4.2 枚举写在相应的.h文件中,不需要单独建立文件
4.3 枚举中的变量以枚举名开头,如:ExamPaperType枚举中包含的变量是ExamPaperTypeExam、ExamPaperTypeCheck、ExamPaperTypeGrade

枚举命名规范

<br/ >

5 方法

5.1 遵循小驼峰命名法
5.2 方法的名称应全部使用有意义的单词组成
5.3 set、get方法:
    5.3.1 set方法命名规范: - (void)setUUID:(NSString *)UUID
    5.3.2 get方法命名规范:- (NSString *)UUID
5.4 init方法:
    5.4.1 必须在if (self = [super init]) {} 中做初始化操作
init方法

<br/ >

6 变量

6.1 遵循小驼峰命名法
6.2 变量必须起有意义的名字
6.3 NSString类型属性:参数必须为(nonatomic, copy)
6.4 NSArray/NSMutableArray类型变量:变量名可以使用加后缀s或Array

NSArray/NSMutableArray类型变量

6.5 NSDictionary/ NSMutableDictionary类型变量:变量名使用后缀Dic
6.6 控件类型变量命名规范:
    6.6.1 UIView类型变量:XXXView
    6.6.2 UIScrollView类型变量:XXXScrollView
    6.6.3 UIImageView类型变量:imgXXX
    6.6.4 UIButton类型变量:btXXX
    6.6.5 UILabel类型变量:lblXXX
    以此类推

<br/ >

7 注释

7.1 变量、方法、枚举使用标准文档注释
    7.1.1 变量注释应详细描述变量用途
    7.1.2 枚举注释应详细描述枚举和每一个元素用途
    7.1.3 方法注释应详细描述方法作用、参数意义、返回值意义

注释

7.2 其他使用单行注释

<br/ >

8 Storyboard ID

8.1 自定义的并只在Storyboard 出现一次的Controller,其Storyboard ID与类型名相同
8.2 其他情况必须起有意义的名字

<br/ >

9 资源文件规范

1.1 资源文件全部放入Supporting Files文件夹下
1.2 图片资源放入Assets.xcassets。可以建立自己的Folder


有什么问题都可以在博文后面留言,或者微博上私信我。

博主是 iOS 妹子一枚。

希望大家一起进步。

我的微博:Lotty周小鱼

描述

因为做项目的时候,需要用到这样布局,也就是通常所说的流式布局

流式布局目标图


思路

最先想到的是用UICollectionView做,因为UICollectionView也可以做成瀑布流的样子,虽然平常看到的都是纵向的,但做成横向应该也不是什么问题。而且UICollectionView可以重用Cell。

但是考虑了实际需求,我们项目需要的是一个条件选择栏,像这样,类似于淘宝:

条件选择栏

实际上,每栏的按钮大约5~8个,而且本来每栏都是一个TableViewCell,所以重用的问题不需要考虑了。

所以最后决定自己封装一个FlowView来实现流式布局的效果。

阅读全文 »

CocoaPods

现在做任何开发都免不了使用第三方库,iOS开发也不例外,每天去逛一逛github成了不可少的必修课。
通常,一些简单的框架拖入相应的.h、.m文件就可以使用了。比如ProgressHUDJSONKit。但是有时候会出现这样的情况:

  1. 三方库需要依赖系统的一些framework,需要手动的添加
  2. 三方库又使用了三方库,需要再去添加

这时候,添加库就变成了十分麻烦的事。
使用 CocoaPods可以省去这些麻烦,只需要把你想添加的库写在一个文件里,CocoaPods可以帮你一键添加、配置。


安装

CocoaPods安装需要ruby环境,但是 Mac 本身已经安装好了 ruby

需要注意的是,ruby 的软件源 https://rubygems.org 被墙了,所以需要更新 ruby 的源换成源替换成国内淘宝的源 https://ruby.taobao.org/ ,在网上看到很多人写成了http://ruby.taobao.org/,`注意这里一定是https`。

1
2
gem sources --remove https://rubygems.org/
gem sources -a https://ruby.taobao.org/

再执行:

1
gem sources -l

如果出现了下图,就说明替换成功了
成功替换

那么,你只需要在终端:

1
2
sudo gem install cocoapods
pod setup

等待一会CocoaPods就安装好了。


使用

新建一个名为 Podfile 的纯文本文件,没有后缀名,放到你项目的根目录。在文件中写入你需要加载的三方库

1
2
3
pod 'JSONKit',       '~> 1.4'
pod 'Masonry'
pod 'FMDB'

一般在三方库的readme文件中也会告诉你需要写什么,比如:
第三方库Masonry的reademe文件

然后在终端输入

1
2
cd "your project home"
pod install

等待一会,CocoaPods会把你需要的所有第三方库下载并且设置好编译参数和依赖。这时会发现项目多了一个.xcworkspace文件,记住,以后都要使用.xcworkspace 文件来打开工程。

更新

如果你又添加新的三方库,可以在Podfile文件中继续添加,然后再终端输入下面的命令CocoaPods就会重新帮你导入。

1
pod update

其他问题

之前遇到一个前辈,他们公司刚刚使用CocoaPods(别问我为啥,我也奇了怪了)。然后他们pod update之后,出现了大量的错误。原因是他们之前使用的三方库太老了,早就已经更新,连方法名都变了。为了预防这一类错误,在Podfile中可以指定版本,像这样:

1
pod 'JSONKit',       '~> 1.4'

有什么问题都可以在博文后面留言,或者微博上私信我。

博主是 iOS 妹子一枚。

希望大家一起进步。

我的微博:Lotty周小鱼

介绍

FMDB现在越来越多的被使用了,作为轻量级数据库框架,FMDB对sqlite做了简单的包装,使得使用更简单。

但是小鱼认为FMDB还是不好用,毕竟不能做到像hebernate一样传一个对象直接保存,直接省去sql语句。之后小鱼打算自己动封装一个框架,至少能够对简单的entity进行一键增删改查。


GitHub

FMDB链接:https://github.com/ccgus/fmdb

阅读全文 »

原文链接: javacodegeeks

翻译: ImportNew.com - LynnShaw

译文链接: http://www.importnew.com/16805.html

经过一段时间的编码(咦,我已经经历了将近20年的编程生涯,快乐的日子总是过得很快),我们开始感谢那些好习惯。因为,你知道…

“任何可能出错的事情,最后都会出错。”

这就是人们为什么喜欢进行“防错性程序设计”的原因。偏执的习惯有时很有意义,有时则不够清晰也不够聪明,也许当你想到这样写的人的时候还会觉得有点怪异。下面是我列出的的个人感觉最有用而又偏执的 10 项 Java 编程技巧。请看:

1. 把字符串常量放在前面

通过把字符串常量放在比较函数equals()比较项的左侧来防止偶然的 NullPointerException 从来都不是一个坏主意,就像这样:

1
2
3
4
5
// Bad
if (variable.equals("literal")) { ... }

// Good
if ("literal".equals(variable)) { ... }

这是毫无疑问的,把一种表达式转换成另一种更好的表达式,并不会失去什么。只要我们的Options是真实存在的(Java 8中 Optional是对可以为空的对象进行的封装),不是吗?讨论一下…

阅读全文 »

本文摘自:《Web全栈工程师的自我修养》

原文地址:http://geek.csdn.net/news/detail/38743

野生程序员是指仅凭对计算机开发的兴趣进入这个行业,从前端到后台一手包揽,但各方面能力都不精通的人。野生程序员有很强大的单兵作战能力,但是在编入“正规军”之后,可能会不适应新的做事方法。

遭遇“野生程序员”

腾讯公司内部的团队很多,在团队管理上有项目和专业两个维度。也就是说,有些团队是项目维度的,整个团队共同维护一个产品,成员来自不同的职业岗位;有些团队是专业维度的,比如一个组都是前端工程师,维护不同的产品。

因为前端组是设计部最接近后台技术的团队,所以团队平时的工作和技术交流分享,都不局限于前端技术领域,还包括很多服务器端或者移动端的技术。从前端到后端,一些技术问题都要我们自己来解决。

在招聘前端工程师的时候,我们对应聘者的要求是,在掌握基本前端技术的前提下,最好有更为全面的技术。这样,即使我们的项目人力结构、平台和方向发生变化的时候,他也能够更加灵活地转移到其他角色中。而且技术的全面更能表现一个人对技术的热情以及较强的学习能力。从团队多样性来讲,多一些技术种类的话,大家在一起也能碰撞出新的火花。

阅读全文 »

目录

[TOC]

博主是不写注释会死星人,以前 java 的时候常用 javadoc ,只要写好注释,然后用 javadoc 生成html 格式的文档。用eclipse和myeclipse都能挂上去。
最近的iOS项目是一个十几个人一起写的项目,很多都初学者,我写主要框架这一块。uml和编码都搞定了,但是为了协作给他人使用,需要一份文档。
除了word和markdown写的reference,api文档也是必不可少的。
所以就开始捣鼓appledoc。在中间遇到不少问题,最后成功的解决了,所以特意分享给大家。

安装Appledoc

Appledoc的github地址:https://github.com/tomaz/appledoc

其实不用下载的,在github项目的readme中已经写了安装方法:

快速安装

打开终端,输入:

1
git clone git://github.com/tomaz/appledoc.git

等待完成后继续输入:

1
sudo sh install-appledoc.sh

等待安装完成。如果出现错误,参考后面的错误解决

brew安装

如果你装了brew,Appledoc官方文档写的是打开终端输入:

1
brew install appledoc

阅读全文 »

iOS中的事件有哪几种

iOS的事件机制一共三种分别是

  1. addTarget方式
  2. delegate代理方式
  3. Notification通知机制

通知机制的原理

  1. iOS的通知分为通知发布者和通知监听者,通知将会放在NSNotificationCenter中。
  2. 通知发布者发布带有信息(或者不带有信息)的通知,放置到NSNotificationCenter中。
  3. 通知监听者可以选择需要监听的对象。
  4. 要注意的是,在编码中是先放置监听者,再放置通知发布者。保证通知发布时已经有监听者在监听。

通知机制的实现

相信你看了下面的代码一定能理解,博主把能打上的注释全部打上了

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
//
// main.m
// day34_通知
//
// Created by Lotty周小鱼 on 15/9/3.
// Copyright (c) 2015年 Lotty周小鱼. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "NotificationListener.h"
#import "NotificationSender.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
// 实例化一个通知发布者
NotificationSender *sender1 = [[NotificationSender alloc] init];
// 实例化一个通知监听者
NotificationListener *listener1 = [[NotificationListener alloc] init];

// 1.获取NSnotificationCenter对象
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

// 2.先监听
// 参数1:要监听通知的对象
// 参数2:该对象的哪个方法监听
// 参数3:被监听的通知的名称
// 参数4:发布通知的对象
// 如果参数3为nil,表示参数4指定的对象发布的所有通知都会被参数2指定的方法监听
// 如果参数4为nil,表示无论哪个给对象,只要发布的通知名称与参数3相同,都会被监听
// 如果参数3、4都为nil 那么所有对象发布的所有通知都会被监听
[notificationCenter addObserver:listener1 selector:@selector(listen:) name:@"通知1" object:sender1];

// 3.向通知中心发布通知
[notificationCenter postNotificationName:@"通知1" object:sender1 userInfo:@{@"title" : @"阅兵", @"content" : @"阅兵将在9点开始"}];

// 4.移除通知,在监听者的dealloc中移除


}
return 0;
}

阅读全文 »

Java程序员出身的博主,刚开始也傻傻的以为iOS中的方法前面+号代表静态方法。然而这是错误的!

在OC中,加号(+)的方法也叫做类方法,也直接用类名来调用的。
但是!它的用来创建一个实例。通常是用来创建实例的工厂方法。比如最常用的[NSArray array],返回的是一个实例化好的数组对象。
所以它和静态不静态没关系。

如果写的demo,就会发现+号方法居然是可以访问非静态变量的,这充分的证明了+号方法不是静态方法。

写下这篇博客,希望和我一样被OC的特殊写法震撼到的程序员能后赶快发现。


有什么问题都可以在博文后面留言,或者微博上私信我。

博主是 iOS 妹子一枚。

希望大家一起进步。

我的微博:Lotty周小鱼

引入

默认情况下,状态栏的文字、图标颜色是黑色
这里写图片描述
但有的时候,比如我们的应用程序背景是深色的,就会看不到状态栏,这时候,我们希望状态栏文字、图标变成白色。
或者,你干脆不让状态栏显示出来。

分析

状态的样式,是交由当前的控制器(viewController、tableViewController等),所以更改状态栏样式需要在控制器的代码里设定。

实现

改变状态栏的颜色:重写- (UIStatusBarStyle)preferredStatusBarStyle方法:

1
2
3
4
5
6
7
8
/**
* 改变状态栏的文字颜色
*
* @return 状态栏风格
*/
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}

隐藏状态栏:重写- (BOOL)prefersStatusBarHidden方法:

1
2
3
4
5
6
7
8
/**
* 隐藏状态栏
*
* @return
*/
- (BOOL)prefersStatusBarHidden {
return YES;
}
阅读全文 »

Object-C中并没有JAVA中的类变量,博主在刚开始时,又是给@property加static修饰,又是给字段加static修饰,都会报错。查阅文档得到以下信息:

  1. static关键字不能用于修饰成员变量
  2. static关键字只能用于修饰局部变量全局变量函数
  3. static修饰局部变量,代表将该局部变量存放到静态存储区
  4. static修饰全局变量,可以限制该全局变量只能被当前源文件访问
  5. static修饰函数,可以限制该函数只能在当前源文件调用

那么现在可以明白OC中的static修饰符跟不少语言中的static不是一回事。

但事实上,类变量确实是面向对象中很有必要的。现在要用另一种方式模拟类变量。

解决方案是:建立static的全局变量,并在实现public的get、set方法,供外部调用

下面给出代码示例,相信你能很快明白其用法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//
// Person.h
// test_command
//
// Created by Lotty周小鱼 on 15/8/11.
// Copyright (c) 2015年 Lotty周小鱼. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Person : NSObject

+(void) setPlanetName: (NSString *)planetName;
+(NSString *) planetName;

@end
阅读全文 »

在网上看过很多介绍,但是还是会晕掉,一大堆绕口的定义,比如下面这些:

nil: 指向oc中对象的空指针,计数器0
Nil: 指向oc中类的空指针
NULL: 指向其他类型的空指针,如一个c类型的内存指针
NSNull: 在集合对象中,表示空值的对象。

这样的显然不能帮助更好的理解,那么结合源码再去理解:

nil: #define nil ((id)0)——–>指向oc中对象的空指针
NULL:#define NULL ((void *)0)——–>NULL其实是C语言中的定义
NSNull: 用在不能使用nil的场合。——–>下面会进行详细描述

NSNull补充

对于NSNull,如果还是困难,那就记住这一句话:NSNull是nil的对象形式。

为什么要这样呢?举个例子,OC中的数组内可以保存所有类型对象,但是不能保存基本类型。
NSArray里不能放入int、double这样类型的,只能放入对象。那么这时候如果你想向数组存入一个空对象,存nil是不合理的,这时就可以用NSNull代替。所以说NSNull是nil的对象形式。

nil和NSNull除了类型完全没有区别吗

实际上是有的:
若obj为nil:
[obj message]将返回NO,而不是NSException
若obj为NSNull:
[obj message]将抛出异常NSException,即NSNull类似于Java的null,可以报空指针错误


有什么问题都可以在博文后面留言,或者微博上私信我。

博主是 iOS 妹子一枚。

希望大家一起进步。

我的微博:Lotty周小鱼

.符号的用法

OC中最刚开始最让人困惑的地方就是.符号,OC中object.property不是一般语言中的引用传递,实际上相当于[object setProperty]或者[object getProperty],可能一开始就容易搞晕了。这给告诉大家到底什么时候是get方法什么时候是set方法。
当object.property出现在等号右边的时候调用的是get方法
XXX = object.property 相当于 XXX = [object getProperty];
当object.property出现在等号左边的时候调用的是set方法
object.property = XXX 相当于 [object setProperty : XXX];
所以当看到object.property = propertyVal时,如果发生了很多不能理解的变化,那一定是在.setProperty(propertyVal)中加了很多逻辑,比如做一些深拷贝。


self代表什么

JAVA中代表类的对象,在OC中可以代表对象也可以代表这个类。
具体的:当self出现在对象方法(动态方法)中,代表调用方法的对象;当self出现在类方法(静态方法)中,代表类。
典型用法:
return [[self alloc] init];//返回一个自己的对象


加号(+)减号(-),并非静态方法

补充在博文中了:iOS学习——objective-c 加号减号,并非静态方法


@class以及@class#import的区别

1.import会包含这个类的所有信息,包括实体变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑,后面会再告诉你。

2.在头文件中, 一般只需要知道被引用的类的名称就可以了。 不需要知道其内部的实体变量和方法,所以在头文件中一般使用@class来声明这个名称是类的名称。 而在实现类里面,因为会用到这个引用类的内部的实体变量和方法,所以需要使用#import来包含这个被引用类的头文件。

3.在编译效率方面考虑,如果你有100个头文件都#import了同一个头文件,或者这些文件是依次引用的,如A–>B, B–>C, C–>D这样的引用关系。当最开始的那个头文件有变化的话,后面所有引用它的类都需要重新编译,如果你的类有很多的话,这将耗费大量的时间。而是用@class则不会。

4.如果有循环依赖关系,如:A–>B, B–>A这样的相互依赖关系,如果使用#import来相互包含,那么就会出现编译错误,如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现。


group

经常写java的程序员们都绝对对习惯性的建好包,分好层。并且习惯性的认为包路径是真实存在的(有相应的文件夹),然而xcode中的group看似是文件夹,实际是只是一个逻辑上的分类,是不存在相应文件件的。
xcode中显示看似是文件夹:
xcode中显示看似是文件夹
实际上却是没有的:
实际上没有文件夹


有什么问题都可以在博文后面留言,或者微博上私信我。

博主是 iOS 妹子一枚。

希望大家一起进步。

我的微博:Lotty周小鱼

学会ios的页面间传值。

和android不同,iOS传值不是通过Intent,而是更直接的方法,直接在被传值类中定义一个存放值的变量,在上一个页面直接将值放入,达到传值的目的。

故事板:

故事板


功能描述:

1
2
3
4
5
6
st=>start: 开始
e=>end: 结束
s1=>operation: 在输入框内输入内容
s2=>operation: 点击下一页按钮
s3=>operation: 在Label中显示上一页输入框内容
st->s1->s2->s3->e

代码:

第一个页面替换自己成自己写的类getDataViewController

  • createDataViewController.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//
// createDataViewController.h
// coderfish003
//
// Created by apple40 on 15-7-20.
// Copyright (c) 2015年 coderfish. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface createDataViewController : UIViewController

// 定义输入框
@property (strong, nonatomic) IBOutlet UITextField *tfCreateData;

@end

阅读全文 »