定制UIWebView的上下文菜单

翻译自:customize the contextual menu of UIWebView. 版权所有, 转载请著明出处,保留链接。

当你点击一下或把手指放在UIWebView对象的一个链接上一秒,一个上下文菜单将会打开并提供了几个选项:复制URL到剪切板,打开链接,一个关闭菜单的按钮。不幸的是没有可以向这个上下文菜单添加额外的菜单选项的API。但是如果你看下iCab Mobile, 你会发现有好多的额外菜单项,这是怎么做到的呢?

首先需要明确的是,你真的不能在默认的标准上下文菜单中增加额外的菜单项。不过,你可以关闭上下文菜单,而使用CSS样式。所以解决方法是关闭默认的菜单,然后重头实现自己的菜单。在实现自定义的菜单前,你必须先捕获tap-and-hold手势,获取手指在屏幕上的坐标,并把它转换成web页面上的坐标,然后查找该坐标处的HTML元素。基于HTML元素,你能确定在上下文菜单中包含哪些菜单项,然后创建并显示上下文菜单。

第一步是在UIWebView中关闭默认的上下文菜单。这很简单,因为只需把web页面的body元素的CSS属性“-webkit-touch-callout”的值设为”none”。我们通过在UIWebView的委托方法“webViewDidFinishLoad:”中调用JavaScript代码来完成:

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
       [webView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitTouchCallout='none';"];
}

现在,默认的上下文菜单将不会出现。

Read More

UIWebView的搜索文本并高亮显示功能

翻译自:search and highlight text in UIWebView. 版权所有, 转载请著明出处,保留链接。

有几个iPhone Apps, 例如如我的”iCab Mobile”, “NewsTap” app, 提供了搜索的特性,即能搜索在UIWebView中显示的文本内容,并且把搜索到的文本内容加黄色背景,以使它们能够很容易的被用户找到。

这篇博客文章将介绍这个特性是怎么实现的。我把这个特性作为UIWebView类的category来实现的,所以你可以很容易在app的UIWebView上应用,使之具有搜索的特性。

首先需要明白的一点是,UIWebView不准许我们直接的访问它的内容,所以我们需要借助javascript。如果你读过我的其他博客文章,你一定已经知道怎么做了。

我们的目标是为新的UIWebView category实现两个新的方法。一个方法是开始搜索并高亮显示搜索的结果,并且返回搜索文本匹配的次数。另一个方法是删除所有加亮过的文本,并且恢复网页原来的布局。

Read More

博客被墙解决办法

版权所有, 转载请著明出处,保留链接。

真有幸,今天被墙了一次,可爱的墙,它永远的在哪里。
奈何,红杏总要出墙来。

wall1

被墙博客域名是: zhiquan.me, IP地址是: 184.171.247.203
首先

>ping 184.171.247.203

是PIND的通的,而

>ping zhiquan.me

PING不通,断定是域名解析过程中出了问题。想了想我的域名服务器在哪边,应该是cloudflare提供的域名服务器,因为我用了它家的CDN加速。当初域名是在godaddy上买的,登入它家的后台,把域名服务器迁移到DNSPod上,这家是国内的,总该不会被……

Read More

Model View View-Model on iOS

翻译自:Functional Reactive Programming on iOS – Ash Furrow. 版权所有, 转载请著明出处,保留链接。

##Model View View-Model on iOS
有一个Zen Buddhist概念,被称为入门者思维,是这样说的:在入门者思维中,有很多种可能,而在专家思想中,却很少。在这本书的写作中,我经常思考这个概念,并反省自己,不要轻易地对新的事物下结论。
在这个精神的指导下,让我们回到刚开始写iOS应用程序的时候。看起来,对象-视图-控制器模型是写iOS应用程序的唯一方式。社区中的先行者们指导你使用MVC, 因为这是他们知道并被Apple推荐的方式。
假如你开发iOS应用程序有段时间了,你一定熟悉MVC的含义:大量的视图控制器。大多数情况下,把业务逻辑和其他一些代码放在视图控制器中是非常方便的,尽管这里不是放置他们最合理的地方。
模型 视图 视图-模型(MVVM), 是来自微软的对MVC的一种替代。我知道,iOS社区历史上对微软不是很感冒,但是他们的软件工程做了一件了不起的工作。MVVM不必拘泥于.Net平台,我们在iOS平台上也能使用。正如我们在这章看到的那样,MVVM在iOS中非常实用,并且能与ReactiveCocoa很好的衔接。使用MVVM能够减少视图控制器中的业务逻辑,这使得代码更具有可测试性。

What is MVVM?

在传统的MVC应用程序中,你有三个组件:模型,视图,控制器。模型是存放数据的地方,而视图是呈现数据的,而控制器协调两者的交互。
这种协调时重要的。模型和视图间是不会注意到各自的存在的,所有的事情都要通过视图控制器。在典型的iOS应用程序中,模型是精练的,意味着他们不包含业务逻辑。视图属于UIKit,它的业务逻辑已经被Apple测试过。剩下视图控制器,是很少被单元测试的。
当新的数据到达时,模型通过键-值观察通知视图控制器,然后视图控制器更新视图。当视图被交互,视图控制器更新模型。

Read More

reactivecocoa in practice

翻译自:Functional Reactive Programming on iOS – Ash Furrow. 版权所有, 转载请著明出处,保留链接。

##reactivecocoa in pratice
本章,我们将在实际的项目中应用ReactiveCocoa,将构建一个简单的500px iphone 应用程序。500px 像Flickr,集聚最好的照片。我喜欢使用它们的API有两个原因:其一,它们的照片看上去很棒;其二,我曾经在哪工作过,从事iOS SDK API的编写工作,所以,我非常熟悉它们的API。
我们将分三部分讲这章。第一,我们将构建一个基本的app实现,叫FunctionalReactivePixels;第二,我们会增加新的视图开发数据加载模块来更好的展现app; 第三,我们会监视app,尽可能的减少状态变量,而使用函数反应式编程。
这将是非常有意思的一章,你可以再GitHub找到我们开发的FunctionReactivePixels app 源码。不幸的是,GitHub源码中有些工作未完成,不过,你跟随这章,你会知道怎么做的。

Read More

introduction to reactivecocoa

翻译自:Functional Reactive Programming on iOS – Ash Furrow. 版权所有, 转载请著明出处,保留链接。

Introduction to ReactiveCocoa

我们在上一章学习的map, filer, fold,是函数式方法。在这一章中我们继续使用它们,这一章是关于ReactiveCocoa和函数反应式编程,这方面会着墨多点。

Installing ReactiveCocoa

ReactiveCocoa可以通过两种方式安装,通过CocoaPods或者子模块。官方上ReactiveCocoa不支持CocoaPods安装,但是开源社区提供了CocoaPods的支持,所以我们将使用该方法。如果你想用子模块安装,请跟随其官方向导,并确认是2.0版本。

为了通过CocoaPods安装ReactiveCocoa,请打开上一章我们创建的文件podfile,并且删除RXCollections行,替换成pod 'ReactiveCocoa', '2.0',替换后podfile文件如下。

platform :ios, "6.0"

target "Playgournd" do

pod 'ReactiveCocoa', '2.1.4'

end

target "PlaygourndTests" do

pod 'ReactiveCocoa', '2.1.4'

end

注意到我们使用了2.0版本,并不是最新的版本。重新在命令行里运行pod install, 这会从工程中删除RXCollections,并且安装ReactiveCocoa。 任何#import声明使用RXCollections方法,都将变的非法,请从你的app代理文件中移除它们。
在这章,我们将我我们的实现代码放在视图控制器实现文件中,而不是app代理文件中,请打开视图的实现文件,别玩了增加如下#import语句.

#import <ReactiveCocoa/ReactiveCocoa.h>

Read More

Functional Programming with RXCollections

###Higher-Order Functions
函数式编程概念的关键是高阶函数。根据WIKI的定义,高阶函数要满足下面两个条件:

  • 函数的输入参数有一个或多个是函数。
  • 返回值是一个函数。

在Objective-C中,常以块(Block)作为函数。

在Apple的基础库Foundation中,我们可以很容易地找到一些高阶函数。例如一列包含数字的数组:

NSArray *array = @[@(), @(2), @(3)];

我们可能需要枚举数组,对每个元素做一些操作。“好”,你说,“我来写个循环吧。”
别这样写,兄弟。有个数组的高阶函数我们可以用。代码如下:

for (NSNumber *number in array){
    NSLog(@"%@", number);
}    

与应用高阶函数的如下代码相同:

[array enumerateObjectsUsingBlock^(NSNumber *number, NSUInteger idx, BOOL *stop){
    NSLog(@"%@", number);
}]

“但是为什么?”,你会问我,“这不是有更多的代码了么?”是的,的确如此,但这只是通往函数式第一步。正如上一章所述,我们抽象了怎样去完成任务,而把注意力集中了任务本身上。这将会有回报,相信我。

在实际中,高阶函数是对我们做事情的抽象,不幸的是,这需要在基础类库中进行扩展。为了更进一步,让我们转向开源社区。

Read More

Philosophy

翻译自:Functional Reactive Programming on iOS – Ash Furrow. 版权所有, 转载请著明出处,保留链接。

Philosophy

这将是一章形而上的章节。“为什么?”,你会问我。“我原以为这是一本关于编码的书?把钱还我!”等下,其实这是一本给开发者变得更善于编程的书,首先,我们来说说,我们为什么要变得更好。

为什么我们想提高,特别是编码者向来被认为是懒的?精湛技艺是为了我们能更懒。我们想写更少的代码,或者更快的写代码。函数反应式编程能帮我们完成这些目标,但这也意味着涉及我们不舒适的领域。

所有的编程意味着要完成某些任务。大部分开发者训练于命令式编程中。命令式编程范式依赖于开发者思考他们怎么去完成这些任务:开发者通过写代码指令改写程序状态来完成。如果编码者以正确的次序写正确的指令,程序输的出会正确的地成它的任务。

听起来有些寻常。

为什么我们被训练成以“怎样”来思考?我想我们以命令式编程,因为我们知道计算机事实上就是这么工作的。CPU周而复始的这样工作着:获取,执行,获取,执行。多么地无聊。

相反,声明式编程使开发者不要去思考怎么完成任务,而让他们把注意力单单集中在他们完成的是什么任务。声明式编程是其他几种范式的概括,我们将稍后讨论。

Wiki 定义:

声明式编程不是以命令式的方式编码来描述想要的结果,列出执行的命令或者步骤。而函数和逻辑式编程语言是声明式编程的特点。

函数反应式编程也在声明式编程范式中,这是这本书的关注点。

Read More