iOS开发初学者入门 | 第九章:相机、相册和社交网络

在这一章节中,你将学会如何在应用中添加相机功能,还会学会如何从相册中获取图片和视频,最后,将学会如何给应用增加分享到Facebook和Twitter的功能。这一章将教会你Swift语言中最重要一部分,这样你能够更快的开发你的App。苹果公司提供了简单快速的方法来把相机图片和分享设计网络集成到一起。

UIImagePickerController

苹果提供了一个简单的类来处理图片和视频。图9-1中的UiImagePickerController看起比较眼熟,被广泛的使用在很多iOS App中。UiImagePickerController能够让相机中的景象直接显示在App中,UiImagePickerController还能够展示相册中的图片,让用户选择图片或者视频。

UiImagePickerController是一个简单的界面,直接在另外的view controller(视图控制器)中模式展示(presented modally)(presented modally是一个Segue类型)。一个modal view controller直接在当前的view controller中显示,有点像是弹出框。modal view controller会从下方滑出,而且只能由用户关闭才能返回之前的界面。modal view controller只能用在临时的交互或者短期的交互中。

图9-1 UiImagePickerController

Page 235

创建UiImagePickerController对象和创建其他对象一样,首先声明一个变量,然后调用初始化:

var imagePicker = UIImagePickerController()

Cameras(相机)

在使用UiImagePickerController之前需要先检查一下当前设备的相机是否可用,在某些情况下,设备虽然有相机但是是不能用的。检查设备相机是否可用的代码:

if UIImagePickerController.isSourceTypeAvailable(.Camera) {
    //Camera is Available
} else {
    //Camera not Available
}

如何相机可用,则可以设置UiImagePickerController来调用相机获取拍摄图片或者视频。把UiImagePickerController设置成相机模式,需要把sourceType属性设置为.Camera

imagePicker.sourceType =  .Camera

Page 236 | Chapter 9 : Camera, Photos, and Social Networks

很多iOS设备有前后两个摄像头。检查前置摄像后可用还是后置摄像头可用,我们使用isCameraDeviceAvailable这个方法。把摄像头的位置传给isCameraDeviceAvailable,然后这个方法就会返回true或者false:

if UIImagePickerController.isCameraDeviceAvailable(.Front) {
    //Front Camera Available
} else {
    //Front Camera Not Available
}

if UIImagePickerController.isCameraDeviceAvailable(.Rear) {
    //Rear Camera Available
} else {
    //Rear Camera Not Available
}

如何当前设备没有可用的摄像头,UiImagePickerController可以让用户从相册中选择图片或者视频。把sourceType属性设置成.PhotoLibrary就可以展示选择图片界面了:

imagePicker.sourceType =  .PhotoLibrary

在iOS模拟器中测试App有时候会有局限性,因为模拟器没有摄像头。永远不要假设设备有相机,总是检查是否有摄像头。为了测试摄像头功能,你必须在真机上运行应用,在真机上运行应用的知识我们将会在第十章进行详细的介绍。

Media Types (媒体类型)

媒体的类型可以设置为图片、视频、和图片+视频。默认设置是图片+视频。想要改变这个设置,需要引入Mobile Core Services framework(Mobile Core Services框架)。

首先点击Project Navigator中的工程名称,显示工程的详细信息,然后滑到底部,找到Linked Frameworks and Libraries这部分,点击左下角的加号,在搜索框中输入MobileCoreServices,选择MobileCoreServices.framework,点击Add按钮。

这样MobileCoreServices.framework文件就添加到你的Project Navigator中了,接着你需要在代码中添加这行代码:

import MobileCoreServices

有了这行代码,MobileCoreServices.framework类就会添加到你代码中,你可以使用这个框架了。下面是每个媒体类型的关键词:

UIImagePickerController | Page 237

kUTTypeImage 相片和图片
kUTTypeMovie 电影和视频
用数组来设置mediaTypes属性,可以存数合适的数值。例如:

imagePicker.mediaTypes = [kUTTypeImage]
//只能拍摄或选择图片
imagePicker.mediaTypes = [kUTTypeMovie]
//只能拍摄或选择视频

Editing(编辑)

苹果甚至提供了缩放图标和修剪视频的功能,叫做editing controls ,把allowsEditing属性设置为true就能开启这些功能了。例如:

imagePicker.allowsEditing = true

这样就能进入编辑界面,你还能获取到编辑后和编辑前的媒体。

Delegates (委托)

UiImagePickerController提供了一些用户基本交互操作的委托更新(delegate updates)(这里不确定delegate updates的翻译是否正确)。例如当用户存储一个新的媒体时,就触发了一个delegate updates。为了能够收到这些updates,我们需要把UiImagePickerController委托到当前的view controller,使用self关键词来表示当前的view controller。例如:

imagePicker.delegate = self

当然,我们还要保证当前的view controller已经遵从了UiImagePickerController协议,遵从协议的方法很简单,就在当前的view controller中添加这行代码:

class ViewController: UIViewController, UIImagePickerControllerDelegate {

因为UiImagePickerController继承自UINavigationController,所以还要遵从UINavigationController协议,这份协议提供UINavigationController如push和pop等事件的updates,你的view controller必须要遵从协议,但是协议中方法(methods)都是可选的。详见代码:

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

Page 238 | Chapter 9 : Camera, Photos, and Social Networks

Working with Images

UIImagePickerControllerDelegate有两个方法来处理媒体,第一个方法是imagePickerController(_: didFinishPickingImage),当相机拍摄了一张图片或者从相册中选择了一张图片后,这个方法就会触发delegate。如果用户是创建或选择的视频,那么这个方法不会被调用。这个方法提供了UIImage参数,来包括新创建的图片。为了能够出发这个事件,我们需要添加下列代码:

func imagePickerController(picker: UIImagePickerController!,didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!){

}

Working with Multiple Media Types

第二个方法更高级一些,是imagePickerController(_:, didFinishPickingMediaWithInfo _:),当用户创建选择了图片视频,这个方法会触发委托。如果sourceType设置为.PhotoLibrary,那么这个方法会在用户选中图片或视频后被调用;如果sourceType设置为.Camera,用户拍摄了图片或视频并且确认保存后,这个方法才会被调用。info参数值为新图片视频提供了额外的信息。
添加下列代码可激活这个事件:

func imagePickerController(picker:UIImagePickerController,didFinishPickingMediaWithInfo info: [NSObject : AnyObject]){
     //media selected
}

info参数还包括mediaType变量,在获取图片视频之前,需要先检查mediaType,获取info参数中的键(key)UIImagePickerControllerMediaType就可以检查mediaType了:

var mediaType = info[UIImagePickerControllerMediaType]

info字典类型参数里面包含了很多关于新拍摄或选择图片视频的信息,下面这些键(key)将会提供所选内容的具体值:

UIImagePickerControllerMediaType
Media type媒体类型,类如:kUTTypeImage 或者 kUTTypeMovie

UIImagePickerControllerOriginalImage
原始未裁剪的图片

UIImagePickerControllerEditedImage
编辑过的图片,只有allowsEditing设置为true

UIImagePickerController | Page 239

UIImagePickerControllerCropRect
将原始图片矩形裁剪

UIImagePickerControllerMediaURL
视频在本地文件中的路径(仅限视频)

UIImagePickerControllerReferenceURL
用于高级视频框架的URL(URL used with advanced video framework)

UIImagePickerControllerMediaMetadata
仅限图片,字典中图片的元数据(Photos only, dictionary full of metadata for image)

所有的这些键都能获取到媒体的更多信息,最常用的键是UIImagePickerControllerMediaType , UIImagePickerControllerOriginalImage , 和 UIImagePickerControllerMediaURL

mediaType覆盖后,运行if语句来检测是图片还是视频(这话原话是Once the mediaType has been recovered, run it through an if statement to detect if itis a video or a photo.我不知道recovered在这里应该如何翻译啊……)。例如:

var mediaType = info[UIImagePickerControllerMediaType! as NSString]
if mediaType == kUTTypeImage as NSString {
    //photo
} else if mediaType == kUTTypeMovie {
    //video
} else {
    //error/missing
}

Images with didFinishPickingMediaWithInfo

如果mediaType的类型是图片,那么图片的会直接传入到 info参数中,新图片会直接从字典中提取出来放入到UIImage,UIImage这个类是用来存储图片的,UIImage的图片传给UIImageView,UIImageView就像是相片的相框,它能把图片装裱起来,图片也能随时更换
UIImageView在用户界面上展示UIImage的内容。例如:

var myImage = info[UIImagePickerControllerOriginalImage] as UIImage

把图片放入UIImageView的方法:把UIImageView的image属性设置为UIImagePickerControllerOriginalImage的键:

imageView.image = myImage

Page 240 | Chapter 9 : Camera, Photos, and Social Networks

Video in didFinishPickingMediaWithInfo

如果mediaType的类型是视频,视频不会直接存储到字典中,而是存储视频文件的路径,用
UIImagePickerControllerMediaURL键来获取。获取路径而不是直接获取视频,有一个非常大的好处,能够节省电量和内存。视频路径可以传递给MPMoviePlayerViewController,在用户屏幕上播放。获取视频的代码:

var videoPath = info[UIImagePickerControllerMediaURL as NSURL

MPMoviePlayerViewController这个类能够让开发视频播放的工作更简单,给MPMoviePlayerViewController一个视频路径,就能播放视频,也能在播放过程中做一些简单的操作。MPMoviePlayerViewController需要Media Player framework这个框架。

首先点击Project Navigator中的工程名称,显示工程的详细信息,然后滑到底部,找到Linked Frameworks and Libraries这部分,点击左下角的加号,在搜索框中输入MediaPlayer,选择MediaPlayer.framework,点击Add按钮。

这样MediaPlayer.framework文件就添加到你的Project Navigator中了,接着你需要打开view controller,然后把鼠标放到import UIKit下方,然后添加这行代码:

import MediaPlayer

这行代码会把MediaPlayer.framework类引入到当前代码中,MediaPlayer.framework中包括MPMoviePlayerViewController这个类。

接着,和创建其他的对象一样,创建一个MPMoviePlayerViewController,接着设置它的contentUIRL属性:

var videoPath = info[UIImagePickerControllerMediaURL as NSURL]
var myMoviePlayerViewController = MPMoviePlayerViewController()
myMoviePlayerViewController.moviePlayer.contentURL = videoPath

Presenting UIImagePickerController

展示新的view controller,我们使用presentViewController这个方法:

self.presentViewController(imagePicker, animated: true, completion: nil)

UIImagePickerController | Page 241

Integrating with Social Networks (加入社交网络功能)

在很多手机应用中,把内容分享到社交网络上已经成为一个核心的特性,然而,把所有的社交网络都整合到App中会非常花费时间,苹果公司提供了Social framwork让开发分享功能更简单。Social framework中包括SLComposeViewController,SLComposeViewController这个类可以让用户把内容分享到Twitter和Facebook。SLComposeViewController使用用户在iPhone设置中填写的登录帐号密码,这就说明开发者不必自己写代码就可以分享到Facebook和Twitter了,用户可以分享文字、链接甚至是图片。

在使用SLComposeViewController之前,我们需要先把Social framework引入到工程当中。首先点击Project Navigator中的工程名称,显示工程的详细信息,然后滑到底部,找到Linked Frameworks and Libraries这部分,点击左下角的加号,在搜索框中输入Social,选择Socail.framework,点击Add按钮。这样Social.framework文件就添加到你的Project Navigator中了,接着你需要打开view controller,然后把鼠标放到import UIKit下方,然后添加这行代码:

import Social

Setting the Social Network (设置社交网络)

上面这行代码会把Social framework引入到view controller中,使SLComposeViewController可以在代码中使用了。在创建SLComposeViewController时需要提供serviceType,serviceType类型有两个选项:
SLServiceTypeFacebook
Facebook
SLServiceTypeTwitter
Twitter

首先要核实需要的service是否可用,使用isAvailableForServiceType(_: )来检查service类型在当前设备是否可用:

if (SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook)) {
     //Facebook available
}

我们可以使用_(forServiceType:)方法来创建SLComposeViewController,有一个forServiceType参数:

if (SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook)) {
       //Facebook available
      var myComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
}

Page 242 | Chapter 9: Camera, Photos, and Social Networks

Setting the Initial Text (设置默认文案)

你还可以给SLComposeViewController设置默认文案,这段默认文案会出现分享界面,提前给用户写好,用户可以直接就分享出去,当然也可以删除或者修改文案。我们用setInitialText(_:)方法来创建默认文案:

var myComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
myComposeViewController.setInitialText("I love this app!")

Adding Images (增加分享图片)

SLComposeViewController也支持图片分享,使用addImage(_:)方法,这个方法有一个UIImage参数:

myComposeViewController.addImage(myImage)

Adding URLs

如果不能分享链接那么分享就没有意义了,SLComposeViewController当然支持分享URL,使用addURL(_:)方法,接收NSURL作为参数。NSURL和字符串非常相似,专门为UIL和文件路径使用。例如:

var myURL = NSURL(string: "http://www.google.com")
myComposeViewController.addURL(myURL)

Presenting SLComposeViewController

最后,SLComposeViewController创建并且设置完成后,需要把SLComposeViewController呈现给用户了,我们使用modally present这个呈现方式,使用presentViewController(_:,animated: completion: )方法,例如:

self.presentViewController(myComposeViewController,animated: true, completion: nil)

这样SLComposeViewController就会展示在用户面前,用户分享内容。如果用户还没有登录社交网络,iOS会引导他到设置中的登录界面完成操作。

现在是时候把知识应用到实践中去了,来创建一个自拍照App吧。

Integrating with Social Networks | Page 243

Exercise: A Selfie App

练习请见此链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容