2017-09-22 14:46:52 jongde1 阅读数 636
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14469 人正在学习 去看看 传智

北京时间9月20日凌晨1点,iOS 11终于迎来了正式版的推送,相信各位小伙伴已经在第一时间进行了升级。iOS 11毫无疑问是一次大规模的系统更新,UI、系统内核、锁屏等多方面都进行了不同程度的改进。小编第一时间为大家整理好了iOS 11优秀 UI Kit的下载资源,并且与大家谈一谈UI Kit背后的iOS 11的新变化。

1、 iOS 11 UI 的新变化

在准备着手设计前,首先我们来梳理一下iOS 11 的设计理念。在iOS系统的长期发展中,随着功能和界面的不断丰富,整个系统日趋复杂,App内部的功能架构也有同样的情况。因此,Apple设计团队在新系统中强调了“指引”这一设计思维,并充分地把这一设计思维贯彻到了iOS 11的方方面面。

此外,我们再来看看苹果设计团队的设计原则:

• 内容凸显的第一原则

• UI元素不与内容竞争,除非是帮助用户去理解潜在功能的作用

在这样的设计思维和原则的基础上,我们从以下几个角度进行分析。

(1)粗体标题导航栏

扁平化设计中,文字排版影响着信息层级的展示的清晰与否,通过文本的字号、字重、颜色等的对比去建立清晰的信息层级,而不用太多的装饰元素。iOS 11中最让你印象深刻的莫过于粗体大标题栏的变化。

如果你想要打造顶层是标签栏结构的APP,这种设计规范就会非常适合,使用粗体大标题能够让用户在大量的标签切换中快速地意识到自己目前所处在的位置;



尤其是对于内容丰富的APP,大量的页面和各种深度的结构层次,在使用大标题后,相信可以起到很好的页面引导作用。



但是我们看到的是,时钟这项系统应用仍然保持了原有的字体排版模式,其原因在于这项应用在内容和功能上互相平行独立,非常容易分辨,如果在每项的界面继续采用大标题,UI元素会潜在对内容造成了竞争,从而违背了基本设计规则。相应的如果是内容和布局类似的APP的话,粗体标题就会起到很好的指示作用。



(2)提升设计层次

“层次(层次)”是UI很重要的元素,让重要的,不重要的东西区隔开来,引导使用者的阅读动线。清晰的层次可以减轻用户的阅读负担,降低信息寻找的脑力消耗,从而让主次关系更加协调统一。

•卡片式和投影

在新版的iOS 11界面中,不少地方采用了卡片式或是宫格式的排列模式,视觉上一致,也易于设计上的迭代。这种主要适用于流量分发的渠道型页面,能够结构层次清晰地展示图文的层级关系,起到规整图文内容的作用;

伴随卡片式的内容一起出现的还有投影的大量使用,令设计元素更加独立醒目,极好的抓住用户的注意力。



•界面布局中的留白

iOS 11的大标题文本中都包含一组带有图片和描述的元素,组元素和组元素之间保持较大的间距。这样的话,设计元素和元素之间保持足够的间距,可以减少用来区分层级关系的不必要装饰元素。



•颜色/字号/字重

iOS 11中也大量使用了颜色深浅、字号大小和文本粗细来展示标签的不同层次,我们可以看到照片APP在iOS 10中章节标题和照片对比不明显,在更新后,章节标题主标题字体变大加粗,副标题字体变大,颜色变为了灰色,整体层次得到了提升。



(3)圆角图标

iOS 11中的大量的图标由2px线性改为了面型,从线框状态变得更加圆润,亲和力。总体来说边角更圆润,空心变为实心,色快感变重,使iOS的视觉更加轻快、柔和。

系统图标中,状态栏讯号强度从•••••改回阶梯式,电量图标的线面比例变得更均衡一些,标签栏图标从空心/实心两态变成全实心粗线条设计,配合整体设计调性。



2、原型设计

在使用Sketch设计完基于iOS 11系统的静态视觉稿后,想要对设计稿进行进一步的交互设计和团队协作的话,推荐在Sketch中安装Mockplus插件,结合Mockplus就可以轻松将Sketch中完成的设计稿转变成可交互原型,从而在Mockplus中进行快速原型设计,并且与团队成员进行协作和批注。



下载地址:https://www.mockplus.cn/download

3、iOS 11 UI Kit资源集锦

(1)Apple官方下载地址(PS、Sketch):

https://developer.apple.com/design/resources/#ios-apps




(2)iOS Design Kit下载:

https://www.iosdesignkit.io/ios11-gui/




(3)UI 8 下载:

https://ui8.net/products/sparks-ios-11-ui-kit



(4)Sketch APP Source下载:

https://www.sketchappsources.com/free-source/2689-ios-11-app-store-design-uu-sketch-freebie-resource.html



(5)Applypixels下载:

https://applypixels.com/template/ios-11-ui-kit/



相信有了这些资源和工具后,大家能够快速地做出适配iOS 11的APP视觉稿和原型,关于更多详细的设计规范和资源,大家可以参考苹果官方的人机交互指南:

苹果人机交互指南

https://developer.apple.com/ios/human-interface-guidelines/overview/themes/

iPhone X适配指南

https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/

2013-12-11 15:41:39 freezing_yu 阅读数 1223
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14469 人正在学习 去看看 传智

又是一大批设计资源,部分内容跟之前文章略有重复。

1. iOS 7 GUI PSD

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


 
 
 

 

 

 

 

 

 

 
 

 

 

35. iOS7 icon grid (PSD)

best-iphone-app-icon-templates-12

 

 

 

 

41. iOS7 & semi-flat iPhone 5 mockup

42. iOS 7 Icon Rounded Corner Radius

43. iOS7 Grid System Icon Template

44. Free iOS7 UI Kit

45. iOS 7 icon template (PSD and Sketch)

46. iOS7 icon guides PSD

 47.Live Blur (Free PSD)

48.iOS 7 UI Kit (Free Download .psd)

 

50.iOS 7 UI (free PSD)

 

52.iOS 7 Icon Grid Blueprint

53.Download: iOS 7 Status Bar Pack

 

2018-11-24 15:46:01 Reflection_ 阅读数 506
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14469 人正在学习 去看看 传智

UIKit

1 overview

UIKit Framework ,UIKit框架事ios 为UI而推出的Frame。

UIKit和其他UI框架构造相似,有 窗口,按钮,列表等class。

UIKit 采用 MVC 模式。

UIKit是 Cocoa Touch 的重要部分。

Cocoa Touch 体系结构

2 MVC 模型

MVC Model,MVC全名是Model View Controller,是模型(model)-视图(view)- 控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数 据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面, 在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。 MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个 逻辑的图形化用户界面的结构中。

Model View Controller
应用程序中用于处理应用程序数据逻辑的部分 应用程序中处理数据显示的部分 应用程序中处理用户交互的部分
通常模型对象负责在数据库中存取数据 通常视图是依据模型数据创建的 通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据

MVC 各个部分间关系

3 Project Config Basic 项目基本设置

da

4 ios应用的生命期

iOS Application Life Cycle
iOS Application Life Cycle

• willFinishLaunchingWithOptions:告诉代理进程启动但还没进入状态保存
• didFinishLaunchingWithOptions:告诉代理启动基本完成程序准备开始运行
• applicationWillResignActive:当应用程序将要入非活动状态执行,在此期间,应
用程序不接收消息或事件,比如来电话了
• applicationDidBecomeActive:当应用程序入活动状态执行,这个刚好跟上面那
个方法相反
• applicationDidEnterBackground:当程序被推送到后台的时候调用。所以要设置
后台继续运行,则在这个函数里面设置即可
• applicationWillEnterForeground:当程序从后台将要重新回到前台时候调用,这
个刚好跟上面的那个方法相反
• applicationWillTerminate:当程序将要退出是被调用,通常是用来保存数据和一
些退出前的清理工作。这个需要要设置UIApplicationExitsOnSuspend的键值
• applicationDidFinishLaunching:当程序载入后执行

5 视图控制器

View Controller ,视图控制器是在MVC模式下,控制视图逻辑的控制器 ;视图控制器管理视图的层次结构;视图控制器处理视图的用户事件,例如点击、手势等…
视图控制器

6 UIView

UIview 是一个UIkit中最基本的类

UIView
UIWindow
UILabel
UITableViewCell
UIScrollView
UITableView
UITextView
UICollectionView
UIPickerView
UIProgressView
UIActivityIndicatiorView
UIIamgeView
UITabBar
UIToolBar
UIControl
UIButton
UIDatePicker
UIPageControl
UISegmentedControl
UITextfield
UISilder
Switch
UINavigationBar
UIActionSheet
UIAlerView
UIWebView

UIView视图与UIWindows窗口是iOS构造用户界面的组件
iOS应用启动后,创建的第一个视图控件是UIWindow
iOS应用通常只有一个窗口(OS X 程序会有多个窗口)

// An highlighted block

UIView的层次结构

ViewFrom 视图外观属性

//View的外观属性 :
	backgroundcolor //设置视图背景颜色 
	alpha           //设置视图透明度
	hidden          //设置视图隐藏状态

ViewGeometry 视图几何属性,视图控制 UIView的 方法

几何属性
Frame(CGRect) = Origin(CGPoint) + Size(CGSize)
Frame(视图的整体框架)相当于 Origin(视图原点,左上角的点的坐标)加上 Size(视图的尺寸)
layer 视图的层次

	//添加子视图
	addSubView        //在视图最上层添加子视图
	InsertSubView     //在视图特定层次添加子视图
	bringSubView      //移动指定子视图到最前
	sendSubView       //移动指定子视图到最后
	exchangeSubView   //交换两个子视图的层次位置
	
	//删除子视图
	removeFromSuperView//删除子视图,使用子视图的对象的方法
	

7 如何开始构造UI

UI Builder,

7.1 故事板

故事板 Storyboard

Xcode 为我们提供一个简单的可视化的UI设计方法,故事板

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可见:storyboard中 可以直接拖拽 组建进入视图控制器下的 View,(SafeArea,是为了边界不被遮挡,顶部信息不被遮挡的一个功能类)

7.2 自动布局

AutoLayout
我们当然可以使用一些计算来为我们的每一个实例的控制器组件(controller )设置origin point,和 size从而达到优雅的布局,这其实是一种可变的布局,随着设备尺寸的变化,设备的横竖变化,动态的UI需求都能够优美实现。

但这样可能会比较复杂,对于一些简单的应用我们没有这样复杂的需求,使用ios 强大的内置的UI自动布局方法事半功倍。

约束条件
约束
横批竖屏问题
经典案例

7.3 Label

7.4 Button

7.5 Switch

7.6 Segment

7.7 Progress

7.8 Slider

7. 9 Stepper

7.10 Test Field

7.11 Alert & Action 提醒 与动作

7.12 Picker & DatePicker 选择器 以及 日期选择器

日期选择器, 特殊的选择器
• UIDatePicker类对日期选择器进行封装
• date:设置或获取日期时间
• locale:设置时区
• datePickerMode:设置模式
• maximumDate:日期上限
• minimumDate:日期下限

选择器
• UIPickerView类对选择器进行封装
• UIPickerViewDelegate:选择器代理协议
• UIPickerViewDataSource:选择器数据源代理协议
• 常用属性与方法
delegate、datasource:代理属性和数据源代理属性
numberOfComponents(in pickerView: UIPickerView) -> Int
pickerView(_ pickerView: UIPickerView, component: Int) -> Int
pickerView(_ pickerView: UIPickerView, forComponent component: Int) -> String?
ickerView(_ pickerView: UIPickerView, inComponent component: Int)
numberOfRowsInComponent titleForRow row: Int, didSelectRow row: Int,

7.13 Scroll & PageScroll 翻页与滚动

• 当信息在一屏中容纳不下时,可考虑使用滚动视图,顾名思义,该视图 可以在屏幕中滚动
• 在滚动过程中,其实是修改原点坐标
• 有些应用每次显示一页,这时使用滚动视图与页视图配合

• UIScrollView类对滚动视图控件进行封装
• UIScrollViewDelegate:滚动视图代理协议
• 常用属性与方法
contentSize:设置滚动视图的内容尺寸
showsVerticalScrollIndicator:隐藏垂直指示条
showsHorizontalScrollIndicator:隐藏水平指示条

7.14 WebViewControl Web视图控件

• UIWebView类对Web视图控件进行封装
• UIWebViewDelegate:滚动视图代理协议
• 常用属性与方法
loadRequest:加载指定URL的网页

7.15 TableView 表视图

在这里插入图片描述

TableView 上有 Section 单元 ,每个单元又分 Cell 子单元

7.16 Custom View 自定义视图

自定义视图显示三角形
自定义TableView Cell
自定义 TableView and Custom Cell

2014-03-19 15:58:59 u012306173 阅读数 250
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14469 人正在学习 去看看 传智

几乎所有的app都包含UI Kit framework中定义的UI 元素,知道这些基本元素的name,roles,capabilities,将会使你在设计UI时做出更好的决定

被UI kit提供的UI 元素大致可以分为四类

Bars:告诉使用者他们在哪里,帮助使用者进行导航控制和开始某个action

Content views:包含app所指定的内容,可以实现scrolling,insertion,deletion,对Item进行重排

controls:执行行为或显示信息

Temporary views:提供给使用者临时性的信息

除了定义UI元素之外,UI kit还定义了实现功能的对象,比如手势识别,drawing,

一个UI元素被当作一个view类型,因为它继承自UIView。一个view对象知道怎样去画他自己,

controller比如buttons和sliders,

content views比如collection views和table views

temporary views比如alert

所有的这些都是view类型

通常用view controller去管理views,一个viewController可以协调各个views之间的显示,在用户interaction之后实现某些功能,实现从一个scene到另外一个scene的过渡






2014-07-29 17:25:15 swibyn 阅读数 1967
  • 苹果iOS应用UI控件开发

    本视频是传智播客iOS学院精心录制的免费精华版UI基础视频,该视频特点在于较大程度保证了知识点的完整性,视频的起点都是针对有一定OC基础的同学

    14469 人正在学习 去看看 传智

测试代码

19.0. IntroductionDates, Calendars, and Events

Event Kit and Event Kit UI frameworks 允许你访问日历数据库,你可以插入、读取、修改events。Event Kit UI framework是你能够呈现内置SDKGUI给用户,让用户修改日历数据库。本章我们先专注于Event Kit framework,并学习Event Kit UI framework

利用Event Kit framework,程序可以偷偷的修改用户的日历数据库。然而这不是好的做法。事实上,苹果公司禁止这样做,他要求我们对日历数据库的任何修改都要通知用户。苹果官方是这么说的:

“如果你的程序需要修改日历数据库,你必须获得用户的许可。应用不应该未在用户的特许下就修改日历数据库”。

iOS有内置日历应用,可以有不同类型的日历。本章中,我们也需要用到不同的日历。为了确保你可以运行本章的代码,你需要创建个iCloud账户,并在手持设备上登陆。

登陆后,可以在日历应用中看到iCloud部分。

为了运行本章代码,你需要引用Event Kit framework,有时候还需要引用Event Kit UI framework,

代码中

#import <EventKit/EventKit.h>

#import <EventKitUI/EventKitUI.h>


iOS模拟器不能模拟日历应用,你需要在真机上测试

本章中得大部分代码专注于读取,处理日历事件。如果你想是使用内置的功能让用户处理日历事件,参看19.10 和19.11


19.1. Requesting Permission to Access Calendars

请求访问许可

调用EKEventStore类的authorizationStatusForEntityType:方法

参数:

EKEntityTypeEvent  请求访问日历的事件

EKEntityTypeReminder:请求访问日历的提醒


返回值:

EKAuthorizationStatusAuthorized :授权

EKAuthorizationStatusDenied:拒绝

EKAuthorizationStatusNotDetermined :未定

EKAuthorizationStatusRestricted:受限



处于保护用户隐私的需要,在访问事件仓库(event store)时需要获得用户许可也就不奇怪了。实际上,如果你没有先获得用户许可,而去访问日历,iOS将锁定应用的的执行并显示授权提示框。


作为苹果王国上的良好居民,你应该先获得用户的许可再去访问数据,

使用EKEventStore类的requestAccessToEntityType:completion:方法来请求


#pragma mark - Events Kit 

-(void)testEKAuthorize

{

   EKEventStore *eventStore = [[EKEventStorealloc] init];

    switch ([EKEventStoreauthorizationStatusForEntityType:EKEntityTypeEvent]){

        caseEKAuthorizationStatusAuthorized:{

            [selfextractEventEntityCalendarsOutOfStore:eventStore];

           break;

        }

        caseEKAuthorizationStatusDenied:{

            [selfdisplayAccessDenied];

           break;

        }

        caseEKAuthorizationStatusNotDetermined:{

            [eventStore requestAccessToEntityType:EKEntityTypeEventcompletion:^(BOOL granted,NSError *error) {

               if (granted){

                    [selfextractEventEntityCalendarsOutOfStore:eventStore];

                }else {

                    [selfdisplayAccessDenied];

                }

            }];

           break;

        }

        caseEKAuthorizationStatusRestricted:{

            [selfdisplayAccessRestricted];

           break;

        }

    }

}


- (void) displayMessage:(NSString *)paramMessage{

   UIAlertView *alertView = [[UIAlertViewalloc] initWithTitle:nil

                                                       message:paramMessage

                                                      delegate:nil

                                             cancelButtonTitle:nil

                                             otherButtonTitles:@"OK",nil];

    [alertViewshow];

}


- (void) displayAccessDenied{

    [selfdisplayMessage:@"Access to the event store is denied."];

}


- (void) displayAccessRestricted{

    [selfdisplayMessage:@"Access to the event store is restricted."];

}


- (void) extractEventEntityCalendarsOutOfStore:(EKEventStore *)paramStore{


   NSArray *calendarTypes = @[

                              @"Local",

                              @"CalDAV",

                              @"Exchange",

                              @"Subscription",

                              @"Birthday",

                              ];

    NSArray *calendars = [paramStorecalendarsForEntityType:EKEntityTypeEvent];

   NSUInteger counter = 1;

   for (EKCalendar *calendarin calendars){

        /* The title of the calendar */

        NSLog(@"Calendar %lu Title = %@",

              (unsignedlong)counter, calendar.title);

        /* The type of the calendar */

        NSLog(@"Calendar %lu Type = %@", (unsignedlong)counter,

              calendarTypes[calendar.type]);

        /* The color that is associated with the calendar */

        NSLog(@"Calendar %lu Color = %@", (unsignedlong)counter,

              [UIColorcolorWithCGColor:calendar.CGColor]);

        /* And whether the calendar can be modified or not */

        if ([calendarallowsContentModifications]){

            NSLog(@"Calendar %lu can be modified.",  (unsignedlong)counter);

        }else {

            NSLog(@"Calendar %lu cannot be modified.", (unsignedlong)counter);

        }

        counter++;

    }

}

打印:

2014-07-25 11:12:26.334 cookbook7_19_1[1033:1103] Calendar 1 Title =工作

2014-07-25 11:12:26.338 cookbook7_19_1[1033:1103] Calendar 1 Type = CalDAV

2014-07-25 11:12:26.340 cookbook7_19_1[1033:1103] Calendar 1 Color = UIDeviceRGBColorSpace 0.8 0.45098 0.882353 1

2014-07-25 11:12:26.342 cookbook7_19_1[1033:1103] Calendar 1 can be modified.

2014-07-25 11:12:26.345 cookbook7_19_1[1033:1103] Calendar 2 Title = Birthdays

2014-07-25 11:12:26.348 cookbook7_19_1[1033:1103] Calendar 2 Type = Birthday

2014-07-25 11:12:26.350 cookbook7_19_1[1033:1103] Calendar 2 Color = UIDeviceRGBColorSpace 0.509804 0.584314 0.686275 1

2014-07-25 11:12:26.352 cookbook7_19_1[1033:1103] Calendar 2 cannot be modified.

2014-07-25 11:12:26.353 cookbook7_19_1[1033:1103] Calendar 3 Title =家庭

2014-07-25 11:12:26.355 cookbook7_19_1[1033:1103] Calendar 3 Type = CalDAV

2014-07-25 11:12:26.357 cookbook7_19_1[1033:1103] Calendar 3 Color = UIDeviceRGBColorSpace 0.203922 0.666667 0.862745 1

2014-07-25 11:12:26.359 cookbook7_19_1[1033:1103] Calendar 3 can be modified.



19.2. Retrieving Calendar Groups on an iOS Device

检索日历组


用户有不同的日历账号,比如iCloud账号和其他独立账号



- (void) findIcloudEventSource{

   EKSource *icloudEventSource = nil;

   EKEventStore *eventStore = [[EKEventStorealloc] init];

   for (EKSource *sourcein eventStore.sources){

       NSLog(@"source=%@",source);

        if (source.sourceType ==EKSourceTypeCalDAV && [source.titlecaseInsensitiveCompare:@"iCloud"]==NSOrderedSame){

            icloudEventSource = source;

//            break;

        }

    }

    

   if (icloudEventSource != nil){

        NSLog(@"The iCloud event source was found = %@", icloudEventSource);

       NSSet *calendars = [icloudEventSource calendarsForEntityType:EKEntityTypeEvent];

       for (EKCalendar *calendarin calendars){

           NSLog(@"Calendar = %@", calendar);

        }

    }else {

        NSLog(@"Could not find the iCloud event source");

    }

}


2014-07-28 17:02:20.630 cookbook7_19_1[2219:907] source=EKSource <0x1c587c90> {UUID = 912FBAEA-98BD-4865-9CB4-7A827FA6C102; type = CalDAV; title = iCloud; externalId = 912FBAEA-98BD-4865-9CB4-7A827FA6C102}

2014-07-28 17:02:20.636 cookbook7_19_1[2219:907] source=EKSource <0x1c587a70> {UUID = C080AFE7-2C99-4975-863A-04152F585707; type = Local; title = Default; externalId = (null)}

2014-07-28 17:02:20.639 cookbook7_19_1[2219:907] source=EKSource <0x1c587be0> {UUID = C6E67576-3F80-4935-8605-A699743C63FA; type = Other; title = Other; externalId = (null)}

2014-07-28 17:02:20.641 cookbook7_19_1[2219:907] The iCloud event source was found = EKSource <0x1c587c90> {UUID = 912FBAEA-98BD-4865-9CB4-7A827FA6C102; type = CalDAV; title = iCloud; externalId = 912FBAEA-98BD-4865-9CB4-7A827FA6C102}

2014-07-28 17:02:20.648 cookbook7_19_1[2219:907] Calendar = EKCalendar <0x1d0a7a70> {title =工作; type = CalDAV; allowsModify = YES; color = #CC73E1FF;}

2014-07-28 17:02:20.650 cookbook7_19_1[2219:907] Calendar = EKCalendar <0x1c5893d0> {title =家庭; type = CalDAV; allowsModify = YES; color = #34AADCFF;}


打开日历软件看下吧




19.3. Adding Events to Calendars

给日历增加事件

从上一节可以看出,日历应用的iCloud中只有工作和家庭两个Calendar,运行本节代码之前再增加一个名字就叫“calendar”


-(void)testInsertEvent

{

    EKEventStore * eventStore = [[EKEventStorealloc] init];

    [selfinsertEventIntoStore:eventStore];

}


- (void) insertEventIntoStore:(EKEventStore *)paramStore{

    EKSource *icloudSource = [self sourceInEventStore:paramStore

                                          sourceType:EKSourceTypeCalDAV

                                         sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }else{

        NSLog(@"icloudSource=%@",icloudSource);

    }

    EKCalendar *calendar = [self calendarWithTitle:@"Calendar"

                                             type:EKCalendarTypeCalDAV

                                         inSource:icloudSource

                                     forEventType:EKEntityTypeEvent];

    if (calendar == nil){

        NSLog(@"Could not find the calendar we were looking for.");

        return;

    }else{

        NSLog(@"calendar=%@",calendar);

    }

    /* The event starts from today, right now */

    NSDate *startDate = [NSDate date];

    /* And the event ends this time tomorrow.

     24 hours, 60 minutes per hour and 60 seconds per minute

     hence 24 * 60 * 60 */

    NSDate *endDate = [startDate dateByAddingTimeInterval:24 *60 * 60];

    /* Create the new event */

    BOOL createdSuccessfully = [self createEventWithTitle:@"My Concert"

                                               startDate:startDate

                                                 endDate:endDate

                                              inCalendar:calendar

                                            inEventStore:paramStore

                                                   notes:nil];

    if (createdSuccessfully){

        NSLog(@"Successfully created the event.");

    }else {

        NSLog(@"Failed to create the event.");

    }

}


- (BOOL)createEventWithTitle:(NSString *)paramTitle

                   startDate:(NSDate *)paramStartDate

                     endDate:(NSDate *)paramEndDate

                  inCalendar:(EKCalendar *)paramCalendar

                inEventStore:(EKEventStore *)paramStore

                       notes:(NSString *)paramNotes{

    BOOL result = NO;

    /* If a calendar does not allow modification of its contents

     then we cannot insert an event into it */

    if (paramCalendar.allowsContentModifications ==NO){

        NSLog(@"The selected calendar does not allow modifications.");

        return NO;

    }

    /* Create an event */

    EKEvent *event = [EKEvent eventWithEventStore:paramStore];

    event.calendar = paramCalendar;

    /* Set the properties of the event such as its title,

     start date/time, end date/time, etc. */

    event.title = paramTitle;

    event.notes = paramNotes;

    event.startDate = paramStartDate;

    event.endDate = paramEndDate;

    /* Finally, save the event into the calendar */

    NSError *saveError = nil;

    result = [paramStoresaveEvent:event

                             span:EKSpanThisEvent

                            error:&saveError];

    if (result == NO){

        NSLog(@"An error occurred = %@", saveError);

    }

    return result;

}


- (EKSource *) sourceInEventStore:(EKEventStore *)paramEventStore

                       sourceType:(EKSourceType)paramType

                      sourceTitle:(NSString *)paramSourceTitle{

    for (EKSource *source in paramEventStore.sources){

        if (source.sourceType == paramType && [source.titlecaseInsensitiveCompare:paramSourceTitle] == NSOrderedSame){

            return source;

        }

    }

    return nil;

}


- (EKCalendar *) calendarWithTitle:(NSString *)paramTitle

                              type:(EKCalendarType)paramType

                          inSource:(EKSource *)paramSource

                      forEventType:(EKEntityType)paramEventType{

    for (EKCalendar *calendar in [paramSource calendarsForEntityType:paramEventType]){

        if ([calendar.title caseInsensitiveCompare:paramTitle] == NSOrderedSame && calendar.type == paramType){

            return calendar;

        }

    }

    return nil;

}


打印:

2014-07-28 17:38:09.590 cookbook7_19_1[2274:907] icloudSource=EKSource <0x208bc910> {UUID = 912FBAEA-98BD-4865-9CB4-7A827FA6C102; type = CalDAV; title = iCloud; externalId = 912FBAEA-98BD-4865-9CB4-7A827FA6C102}

2014-07-28 17:38:09.603 cookbook7_19_1[2274:907] calendar=EKCalendar <0x208beef0> {title = calendar; type = CalDAV; allowsModify = YES; color = #f64f00;}

2014-07-28 17:38:09.665 cookbook7_19_1[2274:907] Successfully created the event.


运行结果表明,calendar的标题不区分大小写。

再到日历应用中看下









19.4. Accessing the Contents of Calendars

检索事件


- (void) readEvents{

    /* Instantiate the event store */

    EKEventStore *eventStore = [[EKEventStorealloc] init];

    EKSource *icloudSource = [self sourceInEventStore:eventStore

                                          sourceType:EKSourceTypeCalDAV

                                         sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }

    EKCalendar *calendar = [self calendarWithTitle:@"Calendar"

                                             type:EKCalendarTypeCalDAV

                                         inSource:icloudSource

                                     forEventType:EKEntityTypeEvent];

    if (calendar == nil){

        NSLog(@"Could not find the calendar we were looking for.");

        return;

    }

    /* The start date will be today */

    NSDate *startDate = [NSDate date];

    /* The end date will be 1 day from today */

    NSDate *endDate = [startDate dateByAddingTimeInterval:24 *60 * 60];

    /* Create the predicate that we can later pass to the

     event store in order to fetch the events */

    NSPredicate *searchPredicate =

    [eventStore predicateForEventsWithStartDate:startDate

                                       endDate:endDate

                                     calendars:@[calendar]];

    /* Make sure we succeeded in creating the predicate */

    if (searchPredicate == nil){

        NSLog(@"Could not create the search predicate.");

        return;

    }

    /* Fetch all the events that fall between

     the starting and the ending dates */

    NSArray *events = [eventStore eventsMatchingPredicate:searchPredicate];

    /* Go through all the events and print their information

     out to the console */

    if (events != nil){

        NSUInteger counter = 1;

        for (EKEvent *event in events){

            NSLog(@"Event %lu Start Date = %@", (unsignedlong)counter,

                  event.startDate);

            NSLog(@"Event %lu End Date = %@", (unsignedlong)counter,

                  event.endDate);

            NSLog(@"Event %lu Title = %@", (unsignedlong)counter,

                  event.title);

            counter++;

        }

    } else {

        NSLog(@"The array of events for this start/end time is nil.");

    }

}


打印:


2014-07-28 18:01:30.908 cookbook7_19_1[2296:907] Event 1 Start Date = 2014-07-28 09:38:09 +0000

2014-07-28 18:01:30.910 cookbook7_19_1[2296:907] Event 1 End Date = 2014-07-29 09:38:09 +0000

2014-07-28 18:01:30.912 cookbook7_19_1[2296:907] Event 1 Title = My Concert



19.5. Removing Events from Calendars

删除事件


-(void)testDeleteEvent

{

    EKEventStore * eventStore = [[EKEventStorealloc] init];

    [selfdeleteEventInStore:eventStore];

}


- (void) deleteEventInStore:(EKEventStore *)paramEventStore{

    EKSource *icloudSource = [self sourceInEventStore:paramEventStore

                                          sourceType:EKSourceTypeCalDAV

                                         sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }

    EKCalendar *calendar = [self calendarWithTitle:@"Calendar"

                                             type:EKCalendarTypeCalDAV

                                         inSource:icloudSource

                                     forEventType:EKEntityTypeEvent];

    if (calendar == nil){

        NSLog(@"Could not find the calendar we were looking for.");

        return;

    }

    /* Create the event first */

    /* The event starts from today, right now */

    NSDate *startDate = [NSDate date];

    /* And the event ends this time tomorrow.

     24 hours, 60 minutes per hour and 60 seconds per minute

     hence 24 * 60 * 60 */

    NSDate *endDate = [startDate dateByAddingTimeInterval:24 *60 * 60];

    NSString *eventTitle = @"My Event";

    BOOL createdSuccessfully = [self createEventWithTitle:eventTitle

                                               startDate:startDate

                                                 endDate:endDate

                                              inCalendar:calendar

                                            inEventStore:paramEventStore

                                                   notes:nil];

    if (createdSuccessfully == NO){

        NSLog(@"Could not create the event.");

    }

    [selfreadEvents];

    BOOL removedSuccessfully = [self removeEventWithTitle:eventTitle

                                               startDate:startDate

                                                 endDate:endDate

                                            inEventStore:paramEventStore

                                              inCalendar:calendar

                                                   notes:nil];

    if (removedSuccessfully){

        NSLog(@"Successfully created and deleted the event");

    } else {

        NSLog(@"Failed to delete the event.");

    }

}


- (BOOL)removeEventWithTitle:(NSString *)paramTitle

                   startDate:(NSDate *)paramStartDate

                     endDate:(NSDate *)paramEndDate

                inEventStore:(EKEventStore *)paramEventStore

                  inCalendar:(EKCalendar *)paramCalendar

                       notes:(NSString *)paramNotes{

    BOOL result = NO;

    /* If a calendar does not allow modification of its contents

     then we cannot insert an event into it */

    if (paramCalendar.allowsContentModifications ==NO){

        NSLog(@"The selected calendar does not allow modifications.");

        return NO; }

    NSPredicate *predicate =  [paramEventStore predicateForEventsWithStartDate:paramStartDate

                                            endDate:paramEndDate

                                          calendars:@[paramCalendar]];

    /* Get all the events that match the parameters */

    NSArray *events = [paramEventStore eventsMatchingPredicate:predicate];

    if ([events count] > 0){

        /* Delete them all */

        for (EKEvent *event in events){

            NSError *removeError = nil;

            /* Do not commit here, we will commit in batch after we have

             removed all the events that matched our criteria */

            if ([paramEventStore removeEvent:event

                                       span:EKSpanThisEvent

                                     commit:NO

                                      error:&removeError] == NO){

                NSLog(@"Failed to remove event %@ with error = %@",event, removeError);

            }

        }

        NSError *commitError = nil;

        if ([paramEventStore commit:&commitError]){

            result =YES;

        } else {

            NSLog(@"Failed to commit the event store.");

        }

    } else {

        NSLog(@"No events matched your input.");

    }

    return result;

}


打印:

2014-07-29 10:56:31.337 cookbook7_19_1[2764:907] Event 1 Start Date = 2014-07-29 02:56:31 +0000

2014-07-29 10:56:31.341 cookbook7_19_1[2764:907] Event 1 End Date = 2014-07-30 02:56:31 +0000

2014-07-29 10:56:31.345 cookbook7_19_1[2764:907] Event 1 Title = My Event

2014-07-29 10:56:31.377 cookbook7_19_1[2764:907] Successfully created and deleted the event


19.6. Adding Recurring Events to Calendars

增加循环事件


本例创建一个每月同一天触发的事件


-(void)testCreateRecurringEvent

{

    EKEventStore * eventStore = [[EKEventStorealloc] init];

    EKSource *icloudSource = [self sourceInEventStore:eventStore

                                          sourceType:EKSourceTypeCalDAV

                                         sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }

    EKCalendar *calendar = [self calendarWithTitle:@"Calendar"

                                             type:EKCalendarTypeCalDAV

                                         inSource:icloudSource

                                     forEventType:EKEntityTypeEvent];

    if (calendar == nil){

        NSLog(@"Could not find the calendar we were looking for.");

        return;

    }

    

    [selfcreateRecurringEventInStore:eventStore inCalendar:calendar];

    

    

}


- (BOOL) createRecurringEventInStore:(EKEventStore *)paramStore inCalendar:(EKCalendar *)paramCalendar{

  

    /* Create an event */

    EKEvent *event = [EKEvent eventWithEventStore:paramStore];

    /* Create an event that happens today and happens every month for a year from now */

    NSDate *eventStartDate = [NSDate date];

    /* The event's end date is one hour from the moment it is created */

    NSTimeInterval NSOneHour = 1 * 60 * 60;

    NSDate *eventEndDate = [eventStartDate dateByAddingTimeInterval:NSOneHour];

    /* Assign the required properties, especially

     the target calendar */

    event.calendar = paramCalendar;

    event.title =@"My Event";

    event.startDate = eventStartDate;

    event.endDate = eventEndDate;

    /* The end date of the recurring rule

     is one year from now */

    NSTimeInterval NSOneYear = 365 * 24 * 60 * 60;

    NSDate *oneYearFromNow = [eventStartDate dateByAddingTimeInterval:NSOneYear];

    /* Create an Event Kit date from this date */

    EKRecurrenceEnd *recurringEnd =[EKRecurrenceEndrecurrenceEndWithEndDate:oneYearFromNow];

    /* And the recurring rule. This event happens every

     month (EKRecurrenceFrequencyMonthly), once a month (interval:1)

     and the recurring rule ends a year from now (end:RecurringEnd) */

    EKRecurrenceRule *recurringRule = [[EKRecurrenceRulealloc]

                                       initRecurrenceWithFrequency:EKRecurrenceFrequencyMonthly

                                      interval:1

                                      end:recurringEnd];


       /* Set the recurring rule for the event */

    event.recurrenceRules =@[recurringRule];

    NSError *saveError = nil;

    /* Save the event */

    if ([paramStoresaveEvent:event span:EKSpanFutureEvents

                       error:&saveError]){

        NSLog(@"Successfully created the recurring event.");

        return YES;

    } else {

        NSLog(@"Failed to create the recurring event %@", saveError);

    }

    return NO;

}

打印:

2014-07-29 11:28:01.269 cookbook7_19_1[2791:907] Successfully created the recurring event.






19.7. Retrieving the Attendees of an Event

检索时间参与人

-(void)testEnumerateTodayEventsInStore

{

    EKEventStore * eventStore = [[EKEventStorealloc] init];

    EKSource *icloudSource = [self sourceInEventStore:eventStore

                                          sourceType:EKSourceTypeCalDAV

                                         sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }

    EKCalendar *calendar = [self calendarWithTitle:@"Calendar"

                                             type:EKCalendarTypeCalDAV

                                         inSource:icloudSource

                                     forEventType:EKEntityTypeEvent];

    if (calendar == nil){

        NSLog(@"Could not find the calendar we were looking for.");

        return;

    }

    

    [selfenumerateTodayEventsInStore:eventStore calendar:calendar];

    

}


- (void) enumerateTodayEventsInStore:(EKEventStore *)paramStore calendar:(EKCalendar *)paramCalendar{

    /* Construct the starting date for today */

    NSDate *startDate = [NSDate date];

    /* The end date will be 1 day from now */

    NSTimeInterval NSOneDay = 1 * 24 * 60 * 60;

    NSDate *endDate = [startDate dateByAddingTimeInterval:NSOneDay];

    /* Create the predicate that we can later pass to

     the event store in order to fetch the events */

    NSPredicate *searchPredicate =

    [paramStore predicateForEventsWithStartDate:startDate

                                       endDate:endDate

                                     calendars:@[paramCalendar]];

    /* Make sure we succeeded in creating the predicate */

    if (searchPredicate == nil){

        NSLog(@"Could not create the search predicate.");

        return;

    }

    /* Fetch all the events that fall between the

     starting and the ending dates */

    NSArray *events = [paramStore eventsMatchingPredicate:searchPredicate];

    /* Array of NSString equivalents of the values

     in the EKParticipantRole enumeration */

    NSArray *attendeeRole = @[

                             @"Unknown",

                             @"Required",

                             @"Optional",

                             @"Chair",

                             @"Non Participant",

                             ];

    /* Array of NSString equivalents of the values

     in the EKParticipantStatus enumeration */

    NSArray *attendeeStatus = @[

                               @"Unknown",

                               @"Pending",

                               @"Accepted",

                               @"Declined",

                               @"Tentative",

                               @"Delegated",

                               @"Completed",

                               @"In Process",

                               ];

    /* Array of NSString equivalents of the values

     in the EKParticipantType enumeration */

    NSArray *attendeeType = @[

                             @"Unknown",

                             @"Person",

                             @"Room",

                             @"Resource",

                             @"Group"

                             ];

    /* Go through all the events and print their information

     out to the console */

    if (events != nil){

        NSUInteger eventCounter = 0;

        for (EKEvent *thisEvent in events){

            eventCounter++;

            NSLog(@"Event %lu Start Date = %@", (unsignedlong)eventCounter, thisEvent.startDate);

            NSLog(@"Event %lu End Date = %@", (unsignedlong)eventCounter, thisEvent.endDate);

            NSLog(@"Event %lu Title = %@", (unsignedlong)eventCounter, thisEvent.title);

            if (thisEvent.attendees == nil || [thisEvent.attendees count] == 0){

                NSLog(@"Event %lu has no attendees", (unsignedlong)eventCounter);

                continue;

            }

            NSUInteger attendeeCounter = 1;

            for (EKParticipant *participant in thisEvent.attendees){

                NSLog(@"Event %lu Attendee %lu Name = %@", (unsignedlong)eventCounter, (unsignedlong)attendeeCounter, participant.name);

                NSLog(@"Event %lu Attendee %lu Role = %@", (unsignedlong)eventCounter,

                      (unsignedlong)attendeeCounter, attendeeRole[participant.participantRole]);

                NSLog(@"Event %lu Attendee %lu Status = %@", (unsignedlong)eventCounter,

                      (unsignedlong)attendeeCounter, attendeeStatus[participant.participantStatus]);

                NSLog(@"Event %lu Attendee %lu Type = %@", (unsignedlong)eventCounter,

                      (unsignedlong)attendeeCounter, attendeeType[participant.participantType]);

                NSLog(@"Event %lu Attendee %lu URL = %@", (unsignedlong)eventCounter, (unsignedlong)attendeeCounter, participant.URL);

                attendeeCounter++;

            }

        }

    } else {

        NSLog(@"The array of events is nil.");

    }

}


打印:

2014-07-29 15:12:54.432 cookbook7_19_1[2899:907] Event 1 Start Date = 2014-07-29 07:12:25 +0000

2014-07-29 15:12:54.435 cookbook7_19_1[2899:907] Event 1 End Date = 2014-07-30 07:12:25 +0000

2014-07-29 15:12:54.437 cookbook7_19_1[2899:907] Event 1 Title = My Concert

2014-07-29 15:12:54.440 cookbook7_19_1[2899:907] Event 1 has no attendees

测试手机,没有联系人的,参与者就不加了



19.8. Adding Alarms to Calendars

增加闹钟

-(void)testAddAlarm

{

    EKEventStore * eventStore = [[EKEventStorealloc] init];

    EKSource *icloudSource = [self sourceInEventStore:eventStore

                                          sourceType:EKSourceTypeCalDAV

                                         sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }

    EKCalendar *calendar = [self calendarWithTitle:@"Calendar"

                                             type:EKCalendarTypeCalDAV

                                         inSource:icloudSource

                                     forEventType:EKEntityTypeEvent];

    if (calendar == nil){

        NSLog(@"Could not find the calendar we were looking for.");

        return;

    }

    [selfaddAlarmToCalendar:calendar inStore:eventStore];

    

}


- (void) addAlarmToCalendar:(EKCalendar *)paramCalendar inStore:(EKEventStore *)paramStore{

    /* The event starts 60 seconds from now */

    NSDate *startDate = [NSDatedateWithTimeIntervalSinceNow:60.0];/* And end the event 20 seconds after its start date */

    NSDate *endDate = [startDate dateByAddingTimeInterval:20.0];

    EKEvent *eventWithAlarm = [EKEvent eventWithEventStore:paramStore];

    eventWithAlarm.calendar = paramCalendar;

    eventWithAlarm.startDate = startDate;

    eventWithAlarm.endDate = endDate;

    /* The alarm goes off 2 seconds before the event happens */

    EKAlarm *alarm = [EKAlarmalarmWithRelativeOffset:-2.0];

    eventWithAlarm.title =@"Event with Alarm";

    [eventWithAlarmaddAlarm:alarm];

    NSError *saveError = nil;

    if ([paramStore saveEvent:eventWithAlarm

                        span:EKSpanThisEvent

                       error:&saveError]){

        NSLog(@"Saved an event that fires 60 seconds from now.");

    } else {

        NSLog(@"Failed to save the event. Error = %@", saveError);

    }

}

打印:

2014-07-29 15:27:55.820 cookbook7_19_1[2924:907] Saved an event that fires 60 seconds from now.








19.9. Handling Event Changed Notifications


处理事件改变通知

当用户修改日历数据库内容时,应用得到通知

-(void)testHandleNotificationsInStore

{

    EKEventStore * eventStore = [[EKEventStorealloc] init];

    EKSource *icloudSource = [self sourceInEventStore:eventStore

                                          sourceType:EKSourceTypeCalDAV

                                         sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }

    EKCalendar *calendar = [self calendarWithTitle:@"Calendar"

                                             type:EKCalendarTypeCalDAV

                                         inSource:icloudSource

                                     forEventType:EKEntityTypeEvent];

    if (calendar == nil){

        NSLog(@"Could not find the calendar we were looking for.");

        return;

    }

    

    [selfaddAlarmToCalendar:calendar inStore:eventStore];

    [selfhandleNotificationsInStore:eventStore];

}


- (void) eventsChanged:(NSNotification *)paramNotification{

    NSMutableArray *invalidatedEvents = [[NSMutableArrayalloc] init];

    NSLog(@"Refreshing array of events...");

    for (EKEvent *event in self.eventsForOneYear){

        if ([event refresh] == NO){

            [invalidatedEventsaddObject:event];

        }

    }

    if ([invalidatedEvents count] > 0){

        [self.eventsForOneYearremoveObjectsInArray:invalidatedEvents];

    }

    NSLog(@"self.eventsForOneYear=%@",self.eventsForOneYear);

}


- (void) handleNotificationsInStore:(EKEventStore *)paramStore{

    EKSource *icloudSource = [selfsourceInEventStore:paramStore

                                           sourceType:EKSourceTypeCalDAV

                                          sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }

    EKCalendar *calendar = [selfcalendarWithTitle:@"Calendar"

                                              type:EKCalendarTypeCalDAV

                                          inSource:icloudSource

                                      forEventType:EKEntityTypeEvent];

    if (calendar == nil){

        NSLog(@"Could not find the calendar we were looking for.");

        return;

    }

    NSTimeInterval NSOneYear =1 * 365 * 24 * 60 * 60;

    

    NSDate *startDate = [NSDatedate];

    NSDate *endDate = [startDate dateByAddingTimeInterval:NSOneYear];

    NSPredicate *predicate =

    [paramStore predicateForEventsWithStartDate:startDate

                                        endDate:endDate

                                      calendars:@[calendar]];

    NSArray *events = [paramStore eventsMatchingPredicate:predicate];

    self.eventsForOneYear = [[NSMutableArray alloc] initWithArray:events];

    NSLog(@"self.eventsForOneYear=%@",self.eventsForOneYear);

    [[NSNotificationCenter defaultCenter]addObserver:self

                                            selector:@selector(eventsChanged:)

                                                 name:EKEventStoreChangedNotification

                                               object:nil];

}


打印:

2014-07-29 15:53:20.519 cookbook7_19_1[3011:907] Saved an event that fires 60 seconds from now.

2014-07-29 15:53:20.540 cookbook7_19_1[3011:907] self.eventsForOneYear=(

    "EKEvent <0x1cd6dba0> {EKEvent <0x1cd6dba0> {title = Event with Alarm; location = (null); calendar = EKCalendar <0x1cd6bed0> {title = calendar; type = CalDAV; allowsModify = YES; color = #f64f00;}; alarms = (\n    \"EKAlarm <0x1cd6ebf0> {triggerInterval = -2.000000}\"\n); URL = (null); lastModified = 2014-07-29 07:53:20 +0000; timeZone = Asia/Shanghai (GMT+0800) offset 28800}; location = (null); startDate = 2014-07-29 07:54:20 +0000; endDate = 2014-07-29 07:54:40 +0000; allDay = 0; floating = 0; recurrence = (null); attendees = (null)}"

)


没有触发eventsChanged:  这是怎么回事呢?

 

在应用中获取所有的事件后,切换到日历应用,删除事件,iOS这将广播EKEventStoreChangedNotification消息,你的应用收到消息,可我的例子怎么没触发消息通知呢。关于应用状态以及如何处理消息,请参见相关章节。




19.10. Presenting Event View Controllers 


使用内置的视图控制器显示日历事件


#import "ViewController.h"

#import <EventKit/EventKit.h>

#import <EventKitUI/EventKitUI.h>

@interface ViewController () <EKEventViewDelegate>


@property (nonatomic,strong) EKEventStore *eventStore;


@end


@implementation ViewController


- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

}


- (void)didReceiveMemoryWarning

{

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

- (void) viewDidAppear:(BOOL)animated{

    [superviewDidAppear:animated];

    static BOOL beenHereBefore = NO;

    if (beenHereBefore){

        return;

    } else {

        beenHereBefore =YES;

    }

    self.eventStore = [[EKEventStorealloc] init];

    switch ([EKEventStoreauthorizationStatusForEntityType:EKEntityTypeEvent]){

        caseEKAuthorizationStatusAuthorized:{

            [selfdisplayEventViewController];

            break;

        }

        caseEKAuthorizationStatusDenied:{

//            [self displayAccessDenied];

            NSLog(@"EKAuthorizationStatusDenied");

            break;

        }

        caseEKAuthorizationStatusNotDetermined:{

            [self.eventStorerequestAccessToEntityType:EKEntityTypeEventcompletion:^(BOOL granted,NSError *error) {

                 if (granted){

                     [selfdisplayEventViewController];

                 }else {

//                     [self displayAccessDenied];

                     

                     NSLog(@"EKAuthorizationStatusDenied");

                 }

            }];

            break;

        }

        caseEKAuthorizationStatusRestricted:{

//            [self displayAccessRestricted];

            NSLog(@"EKAuthorizationStatusRestricted");

            

            break;

        }

    }

}


- (void) displayEventViewController{


    EKSource *icloudSource = [self sourceInEventStore:self.eventStore

                                          sourceType:EKSourceTypeCalDAV

                                         sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }

    NSSet *calendars = [icloudSourcecalendarsForEntityType:EKEntityTypeEvent];

    NSTimeInterval NSOneYear = 1 * 365 * 24.0f * 60.0f * 60.0f;

    NSDate *startDate = [[NSDate date] dateByAddingTimeInterval:-NSOneYear];

    NSDate *endDate = [NSDate date];

    NSPredicate *predicate =

    [self.eventStorepredicateForEventsWithStartDate:startDate

                                            endDate:endDate

                                          calendars:calendars.allObjects];

    NSArray *events = [self.eventStoreeventsMatchingPredicate:predicate];

    if ([events count] > 0){

        EKEvent *event = events[0];

        EKEventViewController *controller = [[EKEventViewControlleralloc] init];

        controller.event = event;

        controller.allowsEditing =YES;

        controller.allowsCalendarPreview =YES;

        controller.delegate =self;

        self.navigationItem.backBarButtonItem =

        [[UIBarButtonItemalloc] initWithTitle:@"Go Back"

                                        style:UIBarButtonItemStylePlain

                                       target:nil

                                       action:nil];

//        [self.navigationController pushViewController:controller

//                                             animated:YES];

        [selfpresentViewController:controller animated:YEScompletion:nil];

    }

}




- (void)eventViewController:(EKEventViewController *)controller didCompleteWithAction:(EKEventViewAction)action{

    switch (action){

        caseEKEventViewActionDeleted:{

            NSLog(@"User deleted the event.");

            break;

        }

        caseEKEventViewActionDone:{

            NSLog(@"User finished viewing the event.");

            break;

        }

        caseEKEventViewActionResponded:{

            NSLog(@"User responsed to the invitation in the event.");

            break;

        }

    }

}




- (EKSource *) sourceInEventStore:(EKEventStore *)paramEventStore

                       sourceType:(EKSourceType)paramType

                      sourceTitle:(NSString *)paramSourceTitle{

    for (EKSource *source in paramEventStore.sources){

        if (source.sourceType == paramType && [source.titlecaseInsensitiveCompare:paramSourceTitle] == NSOrderedSame){

            return source;

        }

    }

    return nil;

}


@end







19.11. Presenting Event Edit View Controllers

使用内置事件编辑器让用户在你的程序里编辑事件



#import "ViewController0.h"

#import <EventKitUI/EventKitUI.h>

#import <EventKit/EventKit.h>


@interface ViewController0 ()<EKEventEditViewDelegate>

@property (nonatomic,strong) EKEventStore *eventStore;

- (IBAction)buttonAction:(id)sender;


@end


@implementation ViewController0


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view.

     self.eventStore = [[EKEventStorealloc] init];

}


- (void)didReceiveMemoryWarning

{

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (void)eventEditViewController:(EKEventEditViewController *)controller

          didCompleteWithAction:(EKEventEditViewAction)action{

    switch (action){

        caseEKEventEditViewActionCanceled:{

            NSLog(@"Cancelled");

            break;

        }

        caseEKEventEditViewActionSaved:{

            NSLog(@"Saved");

            break; }

        caseEKEventEditViewActionDeleted:{

            NSLog(@"Deleted");

            break;

        }

    }

//    [self.navigationController dismissViewControllerAnimated:YES

//                                                  completion:nil];

    [selfdismissViewControllerAnimated:YEScompletion:nil];

}

- (void) displayEventEditController{

    EKSource *icloudSource = [self sourceInEventStore:self.eventStore

                                          sourceType:EKSourceTypeCalDAV

                                         sourceTitle:@"iCloud"];

    if (icloudSource == nil){

        NSLog(@"You have not configured iCloud for your device.");

        return;

    }

    NSSet *calendars = [icloudSourcecalendarsForEntityType:EKEntityTypeEvent];

    NSTimeInterval NSOneYear = 1 * 365 * 24.0f * 60.0f * 60.0f;

    NSDate *startDate = [[NSDate date] dateByAddingTimeInterval:-NSOneYear];

    NSDate *endDate = [NSDate date];

    NSPredicate *predicate =

    [self.eventStorepredicateForEventsWithStartDate:startDate

                                            endDate:endDate

                                          calendars:calendars.allObjects];

    NSArray *events = [self.eventStoreeventsMatchingPredicate:predicate];

    if ([events count] > 0){

        EKEvent *event = events[0];

        EKEventEditViewController *controller = [[EKEventEditViewControlleralloc] init];

        controller.event = event;

        controller.editViewDelegate =self;

//        [self.navigationController presentViewController:controller

//                                                animated:YES

//                                              completion:nil];

        [selfpresentViewController:controller

                          animated:YES

                        completion:nil];


    }

}


- (EKSource *) sourceInEventStore:(EKEventStore *)paramEventStore

                       sourceType:(EKSourceType)paramType

                      sourceTitle:(NSString *)paramSourceTitle{

    for (EKSource *source in paramEventStore.sources){

        if (source.sourceType == paramType && [source.titlecaseInsensitiveCompare:paramSourceTitle] == NSOrderedSame){

            return source;

        }

    }

    return nil;

}


- (IBAction)buttonAction:(id)sender {

    [selfdisplayEventEditController];

}

@end


打印:


2014-07-29 17:13:57.789 cookbook7_19_1[3226:907] Cancelled

2014-07-29 17:14:01.988 cookbook7_19_1[3226:907] Cancelled

2014-07-29 17:14:16.393 cookbook7_19_1[3226:907] Calendar: unable to save: (null)

2014-07-29 17:14:22.549 cookbook7_19_1[3226:907] Remove failed: (null)

2014-07-29 17:14:22.551 cookbook7_19_1[3226:907] Deleted



修改不了,是不是没权限呢,嗨。。。





















  












iOS基础

阅读数 216

iOS自我进阶过程

阅读数 58

没有更多推荐了,返回首页