如何自定义iOS通讯录

苹果给用户提供了自己的通讯录,但是根据业务的需求,需要自定义通讯录,我们就需要根据业务需求来自定义。
首先我们需要知道苹果的提供的一些Foundation、UIKit框架,了解其中的一些特性,可以打开手机查看苹果系统提供的原生的通讯录,可以看到:

1.搜索框
2.右侧搜索条
3.联系人分组
4.添加联系人
5.获取联系人头像及联系方式

根据需求,可以总结出自定义通讯录需要做的一些功能,一项大的功能可以差分成一些小的功能,然后一个一个实现,将复杂的问题差分成小问题解决。

1.自定义搜索框
2.获取首字母
3.权限判断
4.排序
5.自定义搜索
6.自定义联系人界面
(考虑多值的情况,获取通讯录头像)

简答介绍下排序:

IOS项目中会用到对通讯录的联系人或是会员按姓名为关键字排序,因为NSArray并不直接支持对汉字的排序,这就要通过将汉字转换成拼音完成按A~Z的排序,这看起来是个头疼的问题,因为牵扯到汉字转为拼音,获取汉字的首字的首字母,如将“王”变成“W”。

函数原理是:我们知道,在Objective C语言中,字符串是以unicode进行编码的。在unicode字符集中,汉字的编码范围为4E00 到 9FA5 之间(即从第19968开始的20902个字符是中文简体字符)。我们把这些字符的拼音首字母按照顺序都存放在一个char数组中。当我们查找一个汉字的拼音首字母时,只需把这个汉字的unicode码(即char强制转换为int)减去19968,然后用这个数字作为索引去找char数组中存放的字母即可。
给出项目的源码,注释很清楚。代码如:
RYAddressBook.h

#import <Foundation/Foundation.h>
#import "RYPersonInfo.h" 

typedef void (^AddressBookBlock) (NSArray *personInfos); 

@interface RYAddressBook : NSObject 

/**
 * 将数字转化为字母 0~26 1~25=a~z 26=#
 */
NSString* SpellFromIndex(int index); 

/**
 * 获取索引
 */
int Index(NSString *firstSpell);
/**
 * 获取用户所有通讯录信息
 *
 * @return 所有通讯录数据信息数组
 */
+ (void)getPersonInfo:(AddressBookBlock)addressBookBlock; 

/**
 * 根据关键字匹配所有用户信息
 *
 * @param keyWord 匹配关键字
 *
 * @return 匹配到的通讯录数据信息数组
 */
+ (void)searchPersonInfo:(NSString *)keyWord addressBookBlock:(AddressBookBlock)addressBookBlock; 

/**
 * 根据姓名进行数组的重排序
 *
 * @param personInfos 获取的通讯录数据信息数组
 */
+ (NSArray *)sortPersonInfos:(NSArray *)personInfos; 

@end

RYAddressBook.m

#import "RYAddressBook.h" 

@interface RYAddressBook () 

@property (nonatomic, copy) AddressBookBlock addressBookBlock; 

@end 

@implementation RYAddressBook 

NSString* SpellFromIndex(int index)
{
 if (index == 26)
 return @"#";
 else
 return [NSString stringWithFormat:@"%c", [@"A" characterAtIndex:0]+index];
} 

int Index(NSString *firstSpell)
{
 int i = [firstSpell characterAtIndex:0] - [@"a" characterAtIndex:0]; 

 if ([firstSpell isEqualToString:@"#"] || i < 0 || i > 26) {
 return 26;
 } 

 return [firstSpell characterAtIndex:0] - [@"a" characterAtIndex:0];
} 

/**
 * 获取用户所有通讯录信息
 */
+ (void)getPersonInfo:(AddressBookBlock)addressBookBlock
{
 [[self alloc] getPersonInfo:addressBookBlock];
} 

/**
 * 根据关键字匹配所有用户信息
 */
+ (void)searchPersonInfo:(NSString *)keyWord addressBookBlock:(AddressBookBlock)addressBookBlock
{
 [[self alloc] searchPersonInfo:keyWord addressBookBlock:addressBookBlock];
} 

/**
 * 根据姓名进行数组的重排序
 */
+ (NSArray *)sortPersonInfos:(NSArray *)personInfos
{
 return [[self alloc] sortPersonInfos:personInfos];
} 

- (void)getPersonInfo:(AddressBookBlock)addressBookBlock
{
 self.addressBookBlock = addressBookBlock;
 [self searchPersonInfo:@""];
} 

- (void)searchPersonInfo:(NSString *)keyWord addressBookBlock:(AddressBookBlock)addressBookBlock
{
 self.addressBookBlock = addressBookBlock;
 [self searchPersonInfo:keyWord];
} 

- (NSArray *)sortPersonInfos:(NSArray *)personInfos
{
 if (![personInfos isKindOfClass:[NSArray class]]) {
 return nil;
 } 

 NSMutableArray *arr = [NSMutableArray array]; 

 for (int i = 0; i < 27; i++) {
 [arr addObject:[NSMutableArray array]];
 } 

 for (NSObject *obj in personInfos) { 

 if (![obj isKindOfClass:[RYPersonInfo class]]) {
  continue;
 } 

 RYPersonInfo *personInfo = (RYPersonInfo *)obj; 

 NSMutableArray *subArr = [arr objectAtIndex:Index(personInfo.firstSpell)];
 [subArr addObject:personInfo];
 } 

 return arr;
} 

/**
 * 根据关键字查询通讯录信息
 */
- (void)searchPersonInfo:(NSString *)keyWord
{
 CFErrorRef error = NULL;
 ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); 

 // 开始查询通讯录
 ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { 

 if (granted) {
  [self filterContentForSearchText:keyWord];
 }
 });
} 

/**
 * 开始匹配通讯录信息
 */
- (void)filterContentForSearchText:(NSString*)searchText
{
 //如果没有授权则退出
 if (ABAddressBookGetAuthorizationStatus() != kABAuthorizationStatusAuthorized) {
 return;
 } 

 NSArray *blockArray = [NSArray array]; 

 CFErrorRef error = NULL;
 ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); 

 if([searchText length]==0)
 {
 //查询所有
 blockArray = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); 

 } else { 

 //条件查询
 CFStringRef cfSearchText = (CFStringRef)CFBridgingRetain(searchText);
 blockArray = CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook, cfSearchText)); 

 CFRelease(cfSearchText);
 } 

 // 类型转换
 blockArray = transformElements(blockArray); 

 // 返回BlockArray
 self.addressBookBlock(blockArray);
} 

/**
 * 将所有元素转化为JXPersonInfo类型数组
 */
NSArray* transformElements(NSArray* arr)
{
 NSMutableArray *rtnArray = [NSMutableArray array];
 for (int i = 0; i < arr.count; i++) {
 ABRecordRef recordRef = CFBridgingRetain([arr objectAtIndex:i]);
 RYPersonInfo *personInfo = [RYPersonInfo personInfoWithABRecordRef:recordRef]; 

 [rtnArray addObject:personInfo];
 }
 return rtnArray;
}
@end

RYPersonInfo.h

#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h> 

@interface RYPersonInfo : NSObject 

/**
 * 单值信息
 */
#define PROPERTY_STR_READONLY(name) @property (nonatomic, copy) NSString *name;
// 姓
PROPERTY_STR_READONLY(firstName)
// 名
PROPERTY_STR_READONLY(lastName)
// 中间名
PROPERTY_STR_READONLY(middlename)
// 全名
PROPERTY_STR_READONLY(fullName)
// 搜索索引
PROPERTY_STR_READONLY(firstSpell)
// 前缀
PROPERTY_STR_READONLY(prefix)
// 后缀
PROPERTY_STR_READONLY(suffix)
// 昵称
PROPERTY_STR_READONLY(nickname)
// 姓_音标
PROPERTY_STR_READONLY(firstnamePhonetic)
// 名_音标
PROPERTY_STR_READONLY(lastnamePhonetic)
// 中间名_音标
PROPERTY_STR_READONLY(middlenamePhonetic)
// 公司
PROPERTY_STR_READONLY(organization)
// 工作
PROPERTY_STR_READONLY(jobtitle)
// 部门
PROPERTY_STR_READONLY(department)
// 生日
PROPERTY_STR_READONLY(birthday)
// 备忘录
PROPERTY_STR_READONLY(note)
// 第一次创建用户信息的时间
PROPERTY_STR_READONLY(firstknow)
// 最后一次更改用户信息的时间
PROPERTY_STR_READONLY(lastknow)
// 名片类型(company/person)
PROPERTY_STR_READONLY(kind) 

// 多值信息
#define PROPERTY_ARR_READONLY(name) @property (nonatomic, strong) NSArray *name;
// 邮箱
PROPERTY_ARR_READONLY(email)
// 地址
PROPERTY_ARR_READONLY(address)
// 日期
PROPERTY_ARR_READONLY(dates)
// iMessage
PROPERTY_ARR_READONLY(iMessage)
// 电话号码
PROPERTY_ARR_READONLY(phone)
// URL链接
PROPERTY_ARR_READONLY(url) 

#define PROPERTY_IMG_READONLY(name) @property (nonatomic, strong) UIImage *name;
// 图片
//PROPERTY_IMG_READONLY(image)
/**
 * 初始化方法
 *
 * @param ref 联系人属性
 *
 * @return 实例对象
 */
- (id)initWithABRecordRef:(ABRecordRef)ref; 

/**
 * 初始化类方法
 *
 * @param ref 联系人属性
 *
 * @return 实例对象
 */
+ (id)personInfoWithABRecordRef:(ABRecordRef)ref; 

@end

RYPersonInfo.m

#import "RYPersonInfo.h" 

#define nullStrToEmpty(str) \
[str rangeOfString:@"null"].location==0? @"" : str 

/**
 * 单值信息
 */
#define GET_PROPERTY_METHOD(property, property_key) \
- (NSString *)property {\
return (NSString *)CFBridgingRelease(ABRecordCopyValue(_recordRef, property_key));\
} 

/**
 * 多值信息
 */
#define DICT_ADD_STR_FOR_KEY(dict, str, key) \
if (str) {\
[dict setObject:str forKey:key];\
}
#define GET_PROPERTY_SIGLE_VALUE_METHOD(property, property_key)\
- (NSArray *)property\
{\
NSMutableArray *rtnArray = [NSMutableArray array];\
\
ABMultiValueRef ref = ABRecordCopyValue(_recordRef, property_key);\
long count = ABMultiValueGetCount(ref);\
for (int i = 0; i < count; i++)\
{\
NSString* label = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(ref, i));\
NSString* content = (__bridge NSString*)ABMultiValueCopyValueAtIndex(ref, i);\
NSMutableDictionary *dict = [NSMutableDictionary dictionary];\
DICT_ADD_STR_FOR_KEY(dict, content, label);\
\
[rtnArray addObject:dict];\
}\
return rtnArray;\
} 

@interface RYPersonInfo () 

@property (nonatomic , assign)ABRecordRef recordRef; 

@end 

@implementation RYPersonInfo 

- (id)initWithABRecordRef:(ABRecordRef)ref {
 if (self = [super init]) {
 _recordRef = ref;
 }
 return self;
} 

+ (id)personInfoWithABRecordRef:(ABRecordRef)ref {
 return [[[self class] alloc] initWithABRecordRef:ref];
} 

GET_PROPERTY_METHOD( firstName , kABPersonFirstNameProperty);
GET_PROPERTY_METHOD( lastName , kABPersonLastNameProperty);
GET_PROPERTY_METHOD( middlename , kABPersonMiddleNameProperty);
GET_PROPERTY_METHOD( prefix , kABPersonPrefixProperty);
GET_PROPERTY_METHOD( suffix , kABPersonSuffixProperty);
GET_PROPERTY_METHOD( nickname , kABPersonNicknameProperty);
GET_PROPERTY_METHOD( organization , kABPersonOrganizationProperty);
GET_PROPERTY_METHOD( jobtitle , kABPersonJobTitleProperty);
GET_PROPERTY_METHOD( department , kABPersonDepartmentProperty);
GET_PROPERTY_METHOD( birthday , kABPersonBirthdayProperty);
GET_PROPERTY_METHOD( note  , kABPersonNoteProperty);
GET_PROPERTY_METHOD( firstknow , kABPersonCreationDateProperty);
GET_PROPERTY_METHOD( lastknow , kABPersonModificationDateProperty);
GET_PROPERTY_METHOD( firstnamePhonetic , kABPersonFirstNamePhoneticProperty);
GET_PROPERTY_METHOD( lastnamePhonetic , kABPersonLastNamePhoneticProperty);
GET_PROPERTY_METHOD( middlenamePhonetic, kABPersonMiddleNamePhoneticProperty); 

GET_PROPERTY_SIGLE_VALUE_METHOD(email, kABPersonEmailProperty)
GET_PROPERTY_SIGLE_VALUE_METHOD(dates, kABPersonDateProperty)
GET_PROPERTY_SIGLE_VALUE_METHOD(url , kABPersonURLProperty)
GET_PROPERTY_SIGLE_VALUE_METHOD(phone, kABPersonPhoneProperty) 

- (NSString *)kind
{
 NSString *rtnStr = nil;
 CFNumberRef recordType = ABRecordCopyValue(_recordRef, kABPersonKindProperty);
 if (recordType == kABPersonKindOrganization) {
 rtnStr = @"company";
 } else {
 rtnStr = @"person";
 }
 return rtnStr;
} 

- (NSArray *)iMessage
{
 NSMutableArray *rtnArray = [NSMutableArray array]; 

 ABMultiValueRef instantMessage = ABRecordCopyValue(_recordRef, kABPersonInstantMessageProperty);
 for (int i = 1; i < ABMultiValueGetCount(instantMessage); i++)
 {
 NSString* label = (__bridge NSString*)ABMultiValueCopyLabelAtIndex(instantMessage, i);
 NSDictionary* content =(__bridge NSDictionary*) ABMultiValueCopyValueAtIndex(instantMessage, i); 

 NSMutableDictionary *imessageInfoDict = [NSMutableDictionary dictionary];
 NSString* username = [content valueForKey:(NSString *)kABPersonInstantMessageUsernameKey];
 NSString* service = [content valueForKey:(NSString *)kABPersonInstantMessageServiceKey];
 DICT_ADD_STR_FOR_KEY(imessageInfoDict, username, @"username");
 DICT_ADD_STR_FOR_KEY(imessageInfoDict, service, @"service"); 

 NSDictionary *imessageDict = @{label: imessageInfoDict};
 [rtnArray addObject:imessageDict];
 }
 return rtnArray;
} 

-(NSArray *)address
{
 NSMutableArray *rtnArray = [NSMutableArray array]; 

 ABMultiValueRef address = ABRecordCopyValue(_recordRef, kABPersonAddressProperty);
 long count = ABMultiValueGetCount(address);
 for(int i = 0; i < count; i++)
 {
 NSString* addressLabel = (__bridge NSString*)ABMultiValueCopyLabelAtIndex(address, i);
 NSDictionary* personaddress =(__bridge NSDictionary*) ABMultiValueCopyValueAtIndex(address, i); 

 NSMutableDictionary *addressInfoDict = [NSMutableDictionary dictionary];
 NSString* country = [personaddress valueForKey:(NSString *)kABPersonAddressCountryKey];
 NSString* city = [personaddress valueForKey:(NSString *)kABPersonAddressCityKey];
 NSString* state = [personaddress valueForKey:(NSString *)kABPersonAddressStateKey];
 NSString* street = [personaddress valueForKey:(NSString *)kABPersonAddressStreetKey];
 NSString* zip = [personaddress valueForKey:(NSString *)kABPersonAddressZIPKey];
 NSString* coutntrycode = [personaddress valueForKey:(NSString *)kABPersonAddressCountryCodeKey];
 DICT_ADD_STR_FOR_KEY(addressInfoDict, country, @"country");
 DICT_ADD_STR_FOR_KEY(addressInfoDict, city,  @"city");
 DICT_ADD_STR_FOR_KEY(addressInfoDict, state, @"state");
 DICT_ADD_STR_FOR_KEY(addressInfoDict, street, @"street");
 DICT_ADD_STR_FOR_KEY(addressInfoDict, zip,  @"zip");
 DICT_ADD_STR_FOR_KEY(addressInfoDict, coutntrycode, @"coutntrycode"); 

 NSDictionary *addressDict = @{addressLabel: addressInfoDict};
 [rtnArray addObject:addressDict];
 }
 return rtnArray;
} 

//- (UIImage *)image
//{
// NSData *data = (__bridge NSData*)ABPersonCopyImageData(_recordRef);
// return [UIImage imageWithData:data];
//} 

#pragma mark -
#pragma mark - CustomProperty
/**
 * 全名
 */
- (NSString *)fullName
{
 return [NSString stringWithFormat:@"%@%@%@",
  nullStrToEmpty(self.lastName),
  nullStrToEmpty(self.middlename),
  nullStrToEmpty(self.firstName)];
}
/**
 * 首字母
 */
- (NSString *)firstSpell
{
 return getFirstSpell(self.fullName);
} 

/**
 * 输出模型所有信息
 */
- (NSString *)description
{
 return [NSString stringWithFormat:@"%@ -- InfoPacket",
  self.fullName];
} 

/**
 * 获取首字母
 */
NSString* getFirstSpell(NSString *fullName)
{
 NSMutableString *ms = [[NSMutableString alloc] initWithString:fullName];
 CFStringTransform((__bridge CFMutableStringRef)ms, 0, kCFStringTransformMandarinLatin, NO);
 CFStringTransform((__bridge CFMutableStringRef)ms, 0, kCFStringTransformStripDiacritics, NO); 

 if (fullName.length > 0)
 return [[ms substringWithRange:NSMakeRange(0, 1)] lowercaseString];
 else
 return @"#";
} 

@end

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • IOS 通讯录信息读取兼容的实现方法

    IOS 通讯录信息读取兼容的实现方法 项目中有一个功能需要读取通讯录中联系人的手机.在iOS8以前都是可用的,主要使用如下三个代理方法来实现 - (void) peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker - (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController

  • 详解iOS获取通讯录的4种方式

    本文实例为大家分享了iOS获取通讯录的4种方式,供大家参考,具体内容如下 使用场景 一些App通过手机号码来推荐好友,如 微博.支付宝 首先客户端会获取通讯录中的所有手机号然后将这些手机号提交到App服务器中,服务器会查找每个手机号对应的App账号如QQ号码返回到客户端,然后客户端根据服务器返回的账号列表来推荐好友. 获取联系人方式 方案一:AddressBookUI.framework框架 提供了联系人列表界面.联系人详情界面.添加联系人界面等 一般用于选择联系人 方案二:AddressBoo

  • iOS开发中使app获取本机通讯录的实现代码实例

    一.在工程中添加AddressBook.framework和AddressBookUI.framework 二.获取通讯录 1.在infterface中定义数组并在init方法中初始化 复制代码 代码如下: NSMutableArray *addressBookTemp;   - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {     addressBookTemp = [NSMut

  • IOS中获取本地通讯录联系人以及汉字首字母排序

    iOS中获取手机通讯录中的联系人信息: /*** 加载本地联系人*/ - (void)loadLocalContacts { //新建一个通讯录类 ABAddressBookRef addressBooks = nil; if (DeviceVersion < 6.0) { addressBooks = ABAddressBookCreate(); } else { addressBooks = ABAddressBookCreateWithOptions(NULL, NULL); //获取通讯

  • iOS获取手机通讯录方式方法(最新)

    最近学习了iOS获取手机通讯录方式方法,现在分享给大家.希望此文章对各位有所帮助. 一.iOS 9 以前的通讯录框架 AddressBookUI框架:提供了联系人列表界面.联系人详情界面.添加联系人界面等,一般用于选择联系人. AddressBook 框架:纯 C 语言的 API,仅仅是获得联系人数据.没有提供 UI 界面展示,需要自己搭建联系人展示界面. 二. iOS 9 以后最新通讯录框架 ContactsUI 框架:拥有 AddressBookUI 框架的所有功能,使用起来更加的面向对象.

  • IOS 通讯录的访问和修改的实现

    IOS 通讯录的访问和修改的实现 在iOS端可以通过AddressBook或者AddressBookUI两个框架实现,区别是第二个框架带视图,一般使用第一个框架就够了. 下面介绍AddressBook框架的使用,注意这个是C语言框架,使用起来比较麻烦. ①请求授权 先判断授权状态,如果未授权则进行授权. // 1.主动请求授权,先判断授权状态 NSInteger state = ABAddressBookGetAuthorizationStatus(); if (state == kABAuth

  • iOS实现封装一个获取通讯录的工具类详解

    前言 本文给大家介绍了关于iOS如何封装一个获取通讯录工具类的相关内容,iOS获取通讯录一共有4个framework: AddressBook, AddressBookUI, Contacts, ContactsUI; 其中 AddressBook 和 AddressBookUI 已经被iOS9时 deprecated 了, 而推出了Contacts 和 ContactsUI 取代之. 其中 AddressBookUI 和 ContactsUI 是picker出一个界面提供选择一条联系人信息并且

  • 如何自定义iOS通讯录

    苹果给用户提供了自己的通讯录,但是根据业务的需求,需要自定义通讯录,我们就需要根据业务需求来自定义. 首先我们需要知道苹果的提供的一些Foundation.UIKit框架,了解其中的一些特性,可以打开手机查看苹果系统提供的原生的通讯录,可以看到: 1.搜索框 2.右侧搜索条 3.联系人分组 4.添加联系人 5.获取联系人头像及联系方式 根据需求,可以总结出自定义通讯录需要做的一些功能,一项大的功能可以差分成一些小的功能,然后一个一个实现,将复杂的问题差分成小问题解决. 1.自定义搜索框 2.获取

  • Swift自定义iOS中的TabBarController并为其添加动画

    自定义TabBarController 有时候默认的TabBarController不能满足我们的开发需求,比如你想用彩色的图标,系统却只调用图标的轮廓,所以我们需要自己定义一下TabBar. 方法一:修改TabBarController中的TabBar 新建 CustomTabBarController 类继承自 UITabBarController,并在Storyboard中设置: 首先自定义 tabBar 的背景,在 viewDidLoad() 方法中添加: 复制代码 代码如下: // 用

  • 详解iOS Project和Targets配置

    最近开始学习完整iOS项目的开发流程和思路,在实际的项目开发过程中,我们通常需要对项目代码和资料进行版本控制和管理,一般比较常用的SVN或者Github进行代码版本控制和项目管理.我们iOS项目的开发工具Xcode本来就集成了Github的代码控制,所以用GitHub会更方便一些,想具体了解Xcode和GitHub链接具体操作步骤的小伙伴可以戳这里:iOS学习--Xcode9上传项目到GitHub. 创建完项目之后,我们再对一个项目进行代码开发之前,我们首先需要对iOS项目的开发环境进行搭建,我

  • IOS 开发之操作图库自定义控制器

    IOS 开发之操作图库自定义控制器 步骤如下: 新建此类的代理属性必须遵守的协议: 新建PhotoButtonDelegate.h如下: // // PhotoButtonDelegate.h // 作业整理 // // Created by apple on 15/9/16. // Copyright (c) 2015年 LiuXun. All rights reserved. // #import <Foundation/Foundation.h> @class ImageAndPhoto

  • IOS 开发自定义条形ProgressView的实例

    IOS 自定义进度条 ProgressView,好的进度条,让人赏心悦目,在等待的时候不是那么烦躁,也算是增加用户体验吧! 进度条在iOS开发中很常见的,我在项目开发中也写过好多进度条,有好多种类的,条形,圆形等,今天给大家总结一种条形的开发进度条. 简单思路: 1.自定义进度条先继承UIView 建立一个CustomBarProgressView  2.在.H文件中外漏的方法<开始的方法><初始化的方法>  3.在.M文件中 利用定时器改变位置 实现进度条 #效果图 #部分代码

  • iOS组件封装与自动布局自定义表情键盘

    下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自定义表情键盘肿么这么麻烦?下面 将会介绍我们如何用上面提到的东西来定义我们的表情键盘的.下面的内容会比较多,这篇文章还是比较有料的. 还是那句话写技术博客是少不了代码的,下面会结合代码来回顾一下iOS的知识,本篇博文中用到的知识点在前面的博客中都能找到相应的内容,本篇 算是一个小小的功能整合.先来张

  • iOS实现自定义日期选择器示例

    iOS自定义日期选择器,下面只是说明一下怎么用,具体实现请在最后下载代码看看: 效果如下: .h文件解析 选择日期选择器样式 typedef enum{ DateStyleShowYearMonthDayHourMinute = 0, DateStyleShowMonthDayHourMinute, DateStyleShowYearMonthDay, DateStyleShowMonthDay, DateStyleShowHourMinute }XHDateStyle; //日期选择器样式 @

随机推荐