热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

UIPrint​Interaction​Controller

原文链接:http:nshipster.comuiprintinteractioncontroller前言UIKit使用户设备直接打印变得方便起来,而且打印可以根据内容或者纸张大小

原文链接:http://nshipster.com/uiprintinteractioncontroller/

前言

UIKit使用户设备直接打印变得方便起来,而且打印可以根据内容或者纸张大小进行自定义排版。这篇文章的意义在于让你明白在打印的时候如何格式化你的内容,详细阐述不同的方式来展示打印接口。

Xcode6中,打印机模拟器作为硬件IO工具属于其的一部分。

《UIPrint​Interaction​Controller》

《UIPrint​Interaction​Controller》

《UIPrint​Interaction​Controller》

UIKit Printing APIs核心是UIPrintInteractionController。这个类共享实例管理着打印任务还有展示给用户任何UI的配置。同样它还提供了3个级别对格式化内容的控制。

打印任务

首先看下打印选项配置

UIPrintInfo

UIPrintInfo实例中存放着打印任务详情设置。你可以找到如下属性:

  • jobName String:打印任务名字。它会在设备打印中心上展示,对于某些打印机会LCD展示哦。

    • orientation UIPrintInfoOrientation.Portrait(默认)或是.Landscape-通常这个属性被略去如果打印是固定朝向,比如PDF。
    • duplex UIPrintInfoDuplex.None, .ShortEdge, or .LongEdge.。长短边缘设置说明双面打印可被约束,但是None表示不支持双面打印。
    • outputType UIPrintInfoOutputType:让UIKit知道你打印模式。可以为下面任意一种:
      1).General (default):可图文混排,可双面打印
      2).Grayscale:如果内容只含黑体文本的话效果比General好
      3).Photo:彩色或者黑白图片,不允许双面打印,要求胶片纸质
      4)PhotoGrayscale:仅黑白效果的话比3)好

    • printerID String?:特定打印机ID,通过这个检索到该打印机进行预设值。

另外,UIPrintInfo提供了一个dictionaryRepresentation属性,可以被保存并后续用来创建一个新的UIPrintInfo实例。

UIPrintInteractionController设置

这里有些关于UIPrintInteractionController的设置你需要配置下在开始展示打印UI之前。它们包括:

  • printInfo UIPrintInfo:上述的配置
    • printPaper UIPrintPaper:一个简单得类型来描述打印纸得物理性质和可打印的大小;除非是特别的应用,否则这将有UIKit代劳设置。
    • showsNumberOfCopies Bool:当设置为true的时候,用户可以设置拷贝的数量。
    • showsPageRange Bool:当设置为true,让用户在打印介质上选择打印范围。只有当有多页的内容时候这个选项才有意义,对于图片来说这个选项默认关闭。
    • showsPaperSelectionForLoadedPapers Bool:当设置为true并且选择的打印机有多打印纸的选项,那么UI会询问用户选择那个打印纸来打印。

将你的内容格式化

通过UIPrintInteractionController四个不同的属性,你可以选择你想要的内容控制规格(复杂度)。

  • printingItem AnyObject! or printingItems [AnyObject]!:最基础的水平,控制器只是简单得获取可打印的内容(图片或者是PDF)并将他们发送给打印器。
    • printFormatter UIPrintFormatter:下一个等级,你可以使用UIPrintFormatter子类在你的应用中格式化内容。你可以对格式进行一些控制,打印API基本完成剩下的部分。
    • printPageRenderer UIPrintPageRenderer:最高级水平,你可以创建UIPrintPageRenderer子类,混合页面格式还有你自己所涉及的头、尾还有页面内容。

下面根据假想的感恩节菜谱来介绍这些打印属性。

根据printItem(s)进行打印

你可以通过设置UIPrintInteractionController的属性printItemprintItems来打印已存在且可以打印的内容。图片跟PDF可以以图片数据或者通过NSURL地址引用加载到NSData对象等形式提交。为了能够打印,图片必须是UIImage支持的格式。

让我们来看这么一个简单的案例:展示UI当用户点击按钮的时候用来打印图片。处理流程基本相同,无论你要打印什么-配置你的打印信息,搭建打印交互控制器,并且在展示UI之前提供你的打印内容:

@IBAction func print(sender: UIBarButtonItem) {
if UIPrintInteractionController.canPrintURL(imageURL) {
let printInfo = UIPrintInfo(dictionary: nil)
printInfo.jobName = imageURL.lastPathComponent
printInfo.outputType = .Photo
let printCOntroller= UIPrintInteractionController.sharedPrintController()!
printController.printInfo = printInfo
printController.showsNumberOfCopies = false
printController.printingItem = imageURL
printController.presentAnimated(true, completionHandler: nil)
}
}

是吧,很容易吧。。。
《UIPrint​Interaction​Controller》

这若是iPhone则使用presentAnimated(:completionHandler:)方法弹出打印UI。如果是iPad则使用presentFromBarButtonItem(:animated:completionHandler:) or presentFromRect(:inView:animated:completionHandler:)

UIPrintFormatter

UIPrintFormatter类有两个子类(UISimpleTextPrintFormatter and UIMarkupTextPrintFormatter)可以用来格式化文本附加上另外一个UIViewPrintFormatter可以格式化受支持的三种视图内容:UITextView, UIWebView, 和 MKMapView。打印格式有一些属性允许你去用不同的方式定义页面打印区域;

  • contentInsets UIEdgeInsets:整体内容在打印纸四个边缘内偏移一套值。左右适用用每个页面,但是上部偏移只适用于首页。底部偏移忽略。
    • perPageContentInsets UIEdgeInsets(仅限iOS8):每一页格式化后的内容四个边缘内部偏移一套值。
    • maximumContentWidth and maximumContentHeight CGFloat:如果有指定,可以进一步约束内容区域的长与高。

尽管苹果没有文档化说明,所有这些值还是基于每英寸72个点。

两文本类打印格式化与文本一起初始化,文本将会被格式。UISimpleTextPrintFormatter将会处理一半或者属性文本,而UIMarkupTextPrintFormatter使用markupText属性处理和渲染HTML文本。让我们试着发送一个HTML版本的Swiss chard菜谱通过装饰格式化:


let formatter = UIMarkupTextPrintFormatter(markupText: htmlString)
formatter.cOntentInsets= UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72) // 1" margins
printController.printFormatter = formatter

结果如下,漂亮的经过渲染过的HTML页面:
《UIPrint​Interaction​Controller》

另外一方面,使用UIViewPrintFormatter,你可以通过它的viewPrintFormatter属性检索到你想要打印的字段:这里展示下这个格式化在三种支持的视图下的时候怎么完成这个任务:

1) UITextView

《UIPrint​Interaction​Controller》

2) UIWebView

《UIPrint​Interaction​Controller》

3) MKMapView

《UIPrint​Interaction​Controller》

UIPrintPageRenderer

内置的格式化好用,但是大部分对打印纸的控制,你可以通过继承UIPrintPageRenderer来执行。在子类中你可以混合上述打印的格式化使用你自定义的绘制方法为你的应用内容创建很牛X的排版。让我们看下更多打印菜谱的方式,此时使用的是在菜谱中添加了一个头以及在一段文字旁边画了一张图片的页面渲染。

在初始化时,我们保存了我们将要打印的数据,然后设置headerHeight并为菜谱文本创建了装饰文本格式化。

戳这里点击示例查阅

class RecipePrintPageRenderer: UIPrintPageRenderer {
let authorName: String
let recipe: Recipe
init(authorName: String, recipe: Recipe) {
self.authorName = authorName
self.recipe = recipe
super.init()
self.headerHeight = 0.5 * POINTS_PER_INCH
self.footerHeight = 0.0 // default
let formatter = UIMarkupTextPrintFormatter(markupText: recipe.html)
formatter.perPageCOntentInsets= UIEdgeInsets(top: POINTS_PER_INCH, left: POINTS_PER_INCH,
bottom: POINTS_PER_INCH, right: POINTS_PER_INCH * 3.5)
addPrintFormatter(formatter, startingAtPageAtIndex: 0)
}
// ...
}

当你使用一种或者多种打印格式化作为你自定义渲染器的一部分的时候,UIKit查询要进行如此渲染的也页面数。如果你确定要自定义的页面排版,实现umberOfPages()来提供一个正确值。

接下来,我们需要重写drawHeaderForPageAtIndex(:inRect:)来画出我们的自定义头。不幸的是原来每个页面打印格式化中简单内容的内偏值现在不在了,所以我们首先需要让headerRect参数来适应我的边沿,然后简单地划入当前图形上下文。这里有一个简单的drawFooterForPageAtIndex(:inRect:)方法来画足部。

override func drawHeaderForPageAtIndex(pageIndex: Int, var inRect headerRect: CGRect) {
var headerInsets = UIEdgeInsets(top: CGRectGetMinY(headerRect), left: POINTS_PER_INCH, bottom: CGRectGetMaxY(paperRect) - CGRectGetMaxY(headerRect), right: POINTS_PER_INCH)
headerRect = UIEdgeInsetsInsetRect(paperRect, headerInsets)
// author name on left
authorName.drawAtPointInRect(headerRect, withAttributes: nameAttributes, andAlignment: .LeftCenter)
// page number on right
let pageNumberString: NSString = "\(pageIndex + 1)"
pageNumberString.drawAtPointInRect(headerRect, withAttributes: pageNumberAttributes, andAlignment: .RightCenter)
}

最后,让我们实现drawContentForPageAtIndex(:inRect:):

override func drawContentForPageAtIndex(pageIndex: Int, inRect contentRect: CGRect) {
if pageIndex == 0 {
// only use rightmost two inches of contentRect
let imagesRectWidth = POINTS_PER_INCH * 2
let imagesRectHeight = paperRect.height - POINTS_PER_INCH - (CGRectGetMaxY(paperRect) - CGRectGetMaxY(contentRect))
let imagesRect = CGRect(x: CGRectGetMaxX(paperRect) - imagesRectWidth - POINTS_PER_INCH, y: paperRect.origin.y + POINTS_PER_INCH, width: imagesRectWidth, height: imagesRectHeight)
drawImages(recipe.images, inRect: imagesRect)
}
}

当我们自定义页面渲染器实现完成,我们可以设置一个实例作为打印交互控制器的pageRenderer属性,这样我们就准备好打印工作了。

let renderer = RecipePrintPageRenderer(authorName: "Nate Cook", recipe: selectedRecipe)
printController.printPageRenderer = renderer

最后的结果自然比内置格式化器炫多了。

值得注意的是菜单文字是有UIMarkupTextPrintFormatter进行格式化的,而头部还有图片是通过自定义代码格式化的。

《UIPrint​Interaction​Controller》

打印共享页面

使用上述描述的工具,在共享页面添加打印能力变得简单起来。与使用UIPrintInteractionController弹出打印UI不同,我们传递我们自己配置UIPrintInfo以及打印项,格式化,或者是渲染器给UIActivityViewController。如果用户在共享页面选择打印按钮,打印UI会完整展示我们的设置。

@IBAction func openShareSheet() {
let printInfo = ...
let formatter = ...
let activityItems = [printInfo, formatter, textView.attributedText]
let activityCOntroller= UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
presentViewController(activityController, animated: true, completion: nil)
}

UIPrintInfoUIPrintFormatter以及UIPrintPageRenderer的子类可以以活动的形式传递给UIActivityViewController的时候,它们似乎都不遵循UIActivityItemSource协议,所以你会看到一个告警”Unknown activity items.”

跳过打印UI

现在iOS8可以略过打印UI。你可以在应用中提供一个方式让用户选中一个打印机进行更方便的使用UIPrinterPickerController。它在构造器中接受UIPrinter实例选项来进行预选择,使用上述同样的弹出选项,并且在用户选择她得打印器的时候有一个响应句柄:

let printerPicker = UIPrinterPickerController(initiallySelectedPrinter: savedPrinter)
printerPicker.presentAnimated(true) {
(printerPicker, userDidSelect, error) in
if userDidSelect {
self.savedPrinter = printerPicker.selectedPrinter
}
}

现在你可以让你的UIPrintInteractionController通过调用printToPrinter(:completionHandler:)通过保存过的打印机进行直接打印而不是通过调用present...方法。

最后一个建议。。。略。。。呵呵


推荐阅读
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文详细介绍了PHP中与URL处理相关的三个函数:http_build_query、parse_str和查询字符串的解析。通过示例和语法说明,讲解了这些函数的使用方法和作用,帮助读者更好地理解和应用。 ... [详细]
  • Firefox火狐浏览器关闭到http://detectportal.firefox.com的流量问题解决办法
    本文介绍了使用Firefox火狐浏览器时出现关闭到http://detectportal.firefox.com的流量问题,并提供了解决办法。问题的本质是因为火狐默认开启了Captive portal技术,当连接需要认证的WiFi时,火狐会跳出认证界面。通过修改about:config中的network.captive-portal-service.en的值为false,可以解决该问题。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
author-avatar
Vin-莹持_366
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有